Version 0.6.0.0

svn merge -r 24101:24454 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@24460 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/client/tools/buildbot_annotated_steps.py b/client/tools/buildbot_annotated_steps.py
index d65c4e0..347b483 100755
--- a/client/tools/buildbot_annotated_steps.py
+++ b/client/tools/buildbot_annotated_steps.py
@@ -218,7 +218,8 @@
       match = re.search('dart-editor-fyi(.*)', name)
       name = 'dart-editor' + match.group(1)
       # In case we're an FYI builder, run 'tools/bots/editor.py'.
-      status = ProcessBot(name, 'editor')
+      status = ProcessBot(name, 'editor',
+                          custom_env=EnvironmentWithoutBotoConfig())
     else:
       # Run the old annotated steps script
       status = ProcessTools('release', name, version)
diff --git a/pkg/analyzer_experimental/bin/coverage.dart b/pkg/analyzer_experimental/bin/coverage.dart
index 87be02e..ed6d2f6 100644
--- a/pkg/analyzer_experimental/bin/coverage.dart
+++ b/pkg/analyzer_experimental/bin/coverage.dart
@@ -4,19 +4,86 @@
 
 library runtime.coverage;
 
-import "package:logging/logging.dart" as log;
+import 'dart:io';
 
-import 'package:analyzer_experimental/src/services/runtime/coverage_impl.dart';
+import 'package:args/args.dart';
+
+import 'package:analyzer_experimental/src/services/runtime/log.dart' as log;
+import 'package:analyzer_experimental/src/services/runtime/coverage/coverage_impl.dart';
 
 
 main() {
-  var logger = log.Logger.root;
-  logger.level = log.Level.ALL;
-  logger.onRecord.listen((log.LogRecord record) {
-    String levelString = record.level.toString();
-    while (levelString.length < 6) levelString += ' ';
-    print('${record.time}: ${levelString} ${record.message}');
-  });
-  // TODO(scheglov) get script from options
-  new CoverageServer('/Users/scheglov/dart/Test/bin').start();
-}
\ No newline at end of file
+  ArgResults options;
+  try {
+    options = _argParser.parse(new Options().arguments);
+  } on FormatException catch (e) {
+    print(e.message);
+    print('Run "coverage --help" to see available options.');
+    exit(ERROR);
+  }
+
+  if (options['help']) {
+    printUsage();
+    return;
+  }
+
+  // No script to run.
+  if (options.rest.isEmpty) {
+    printUsage('<No script to run specified>');
+    exit(ERROR);
+  }
+
+  // More than one script specified.
+  if (options.rest.length != 1) {
+    print('<Only one script should be specified>');
+    exit(ERROR);
+  }
+
+  var scriptPath = options.rest[0];
+
+  // Validate that script file exists.
+  if (!new File(scriptPath).existsSync()) {
+    print('<File "$scriptPath" does not exist>');
+    exit(ERROR);
+  }
+
+  // Prepare output file path.
+  var outPath = options['out'];
+  if (outPath == null) {
+    printUsage('No --out specified.');
+    exit(ERROR);
+  }
+
+  // Configure logigng.
+  log.everything();
+  log.toConsole();
+
+  // Run script.
+  runServerApplication(scriptPath, outPath);
+}
+
+
+final ArgParser _argParser = new ArgParser()
+    ..addFlag('help', negatable: false, help: 'Print this usage information.')
+    ..addOption(
+        'level',
+        help: 'The level of the coverage.',
+        allowed: ['method', 'block', 'statement'],
+        defaultsTo: 'statement')
+    ..addOption('out', help: 'The output file with statistics.')
+    ..addOption(
+        'port',
+        help: 'The port to run server on, if 0 select any.',
+        defaultsTo: '0');
+
+
+printUsage([var description = 'Code coverage tool for Dart.']) {
+  var usage = _argParser.getUsage();
+  print('$description\n');
+  print('Usage: coverage [options] <script>\n');
+  print('$usage\n');
+}
+
+
+/// General error code.
+const ERROR = 1;
diff --git a/pkg/analyzer_experimental/lib/analyzer.dart b/pkg/analyzer_experimental/lib/analyzer.dart
index 30f8857..47ca97c 100644
--- a/pkg/analyzer_experimental/lib/analyzer.dart
+++ b/pkg/analyzer_experimental/lib/analyzer.dart
@@ -6,6 +6,8 @@
 
 import 'dart:io';
 
+import 'package:pathos/path.dart' as pathos;
+
 import 'src/error.dart';
 import 'src/generated/ast.dart';
 import 'src/generated/error.dart';
@@ -13,7 +15,6 @@
 import 'src/generated/parser.dart';
 import 'src/generated/scanner.dart';
 import 'src/generated/source_io.dart';
-import 'src/utils.dart';
 
 export 'src/error.dart';
 export 'src/generated/ast.dart';
@@ -25,7 +26,7 @@
   var contents = new File(path).readAsStringSync();
   var errorCollector = new _ErrorCollector();
   var sourceFactory = new SourceFactory.con2([new FileUriResolver()]);
-  var source = sourceFactory.forUri(pathToFileUri(path).toString());
+  var source = sourceFactory.forUri(pathos.toUri(path).toString());
   var scanner = new StringScanner(source, contents, errorCollector);
   var token = scanner.tokenize();
   var parser = new Parser(source, errorCollector);
diff --git a/pkg/analyzer_experimental/lib/options.dart b/pkg/analyzer_experimental/lib/options.dart
index 83d5585..dd841f0 100644
--- a/pkg/analyzer_experimental/lib/options.dart
+++ b/pkg/analyzer_experimental/lib/options.dart
@@ -153,7 +153,7 @@
 
   static String _getVersion() {
     try {
-      Path path = new Path(new Options().script);
+      Path path = new Path(Platform.script);
       Path versionPath = path.directoryPath.append('..').append('version');
       File versionFile = new File.fromPath(versionPath);
       return versionFile.readAsStringSync().trim();
@@ -251,7 +251,6 @@
       }
     }
 
-    print(filtered);
     return filtered;
   }
 
diff --git a/pkg/analyzer_experimental/lib/src/analyzer_impl.dart b/pkg/analyzer_experimental/lib/src/analyzer_impl.dart
index 5d8fc4c..4e46d61 100644
--- a/pkg/analyzer_experimental/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_experimental/lib/src/analyzer_impl.dart
@@ -81,7 +81,6 @@
       } else {
         packageDirectory = getPackageDirectoryFor(sourceFile);
       }
-      print('packageDirectory: ${packageDirectory.getPath()}');
       if (packageDirectory != null) {
         resolvers.add(new PackageUriResolver([packageDirectory]));
       }
diff --git a/pkg/analyzer_experimental/lib/src/generated/ast.dart b/pkg/analyzer_experimental/lib/src/generated/ast.dart
index 0adebba..6b7d525 100644
--- a/pkg/analyzer_experimental/lib/src/generated/ast.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/ast.dart
@@ -11,25 +11,25 @@
 import 'utilities_dart.dart';
 import 'element.dart';
 /**
- * The abstract class {@code ASTNode} defines the behavior common to all nodes in the AST structure
+ * The abstract class `ASTNode` defines the behavior common to all nodes in the AST structure
  * for a Dart program.
  * @coverage dart.engine.ast
  */
 abstract class ASTNode {
 
   /**
-   * The parent of the node, or {@code null} if the node is the root of an AST structure.
+   * The parent of the node, or `null` if the node is the root of an AST structure.
    */
   ASTNode _parent;
 
   /**
-   * A table mapping the names of properties to their values, or {@code null} if this node does not
+   * A table mapping the names of properties to their values, or `null` if this node does not
    * have any properties associated with it.
    */
   Map<String, Object> _propertyMap;
 
   /**
-   * 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
+   * A comparator that can be used to sort AST nodes in lexical order. In other words,`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.
    */
@@ -43,7 +43,7 @@
   accept(ASTVisitor visitor);
 
   /**
-   * @return the {@link ASTNode} of given {@link Class} which is {@link ASTNode} itself, or one of
+   * @return the [ASTNode] of given [Class] which is [ASTNode] itself, or one of
    * its parents.
    */
   ASTNode getAncestor(Type enclosingClass) {
@@ -63,7 +63,7 @@
 
   /**
    * 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
+   * source range. This is equivalent to `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
@@ -104,16 +104,16 @@
   }
 
   /**
-   * Return this node's parent node, or {@code null} if this node is the root of an AST structure.
-   * <p>
+   * Return this node's parent node, or `null` if this node is the root of an AST structure.
+   *
    * 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
+   * @return the parent of this node, or `null` if none
    */
   ASTNode get parent => _parent;
 
   /**
-   * Return the value of the property with the given name, or {@code null} if this node does not
+   * Return the value of the property with the given name, or `null` if this node does not
    * have a property with the given name.
    * @return the value of the property with the given name
    */
@@ -140,15 +140,15 @@
   }
 
   /**
-   * Return {@code true} if this node is a synthetic node. A synthetic node is a node that was
+   * Return `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
+   * have a length of zero (`0`).
+   * @return `true` if this node is a synthetic node
    */
-  bool isSynthetic() => false;
+  bool get isSynthetic => false;
 
   /**
-   * Set the value of the property with the given name to the given value. If the value is{@code null}, the property will effectively be removed.
+   * Set the value of the property with the given name to the given value. If the value is`null`, the property will effectively be removed.
    * @param propertyName the name of the property whose value is to be set
    * @param propertyValue the new value of the property
    */
@@ -201,7 +201,7 @@
   }
 
   /**
-   * If the given child is not {@code null}, use the given visitor to visit it.
+   * If the given child is not `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
    */
@@ -222,7 +222,7 @@
   final int hashCode = ++_hashCodeGenerator;
 }
 /**
- * The interface {@code ASTVisitor} defines the behavior of objects that can be used to visit an AST
+ * The interface `ASTVisitor` defines the behavior of objects that can be used to visit an AST
  * structure.
  * @coverage dart.engine.ast
  */
@@ -330,13 +330,13 @@
   R visitWithClause(WithClause node);
 }
 /**
- * Instances of the class {@code AdjacentStrings} represents two or more string literals that are
+ * Instances of the class `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}+
+ * adjacentStrings ::=[StringLiteral string] [StringLiteral string]+
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -380,14 +380,14 @@
   }
 }
 /**
- * The abstract class {@code AnnotatedNode} defines the behavior of nodes that can be annotated with
+ * The abstract class `AnnotatedNode` defines the behavior of nodes that can be annotated with
  * both a comment and metadata.
  * @coverage dart.engine.ast
  */
 abstract class AnnotatedNode extends ASTNode {
 
   /**
-   * The documentation comment associated with this node, or {@code null} if this node does not have
+   * The documentation comment associated with this node, or `null` if this node does not have
    * a documentation comment associated with it.
    */
   Comment _comment;
@@ -433,7 +433,7 @@
   }
 
   /**
-   * Return the documentation comment associated with this node, or {@code null} if this node does
+   * Return the documentation comment associated with this node, or `null` if this node does
    * not have a documentation comment associated with it.
    * @return the documentation comment associated with this node
    */
@@ -479,8 +479,8 @@
   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
+   * Return `true` if the comment is lexically before any annotations.
+   * @return `true` if the comment is lexically before any annotations
    */
   bool commentIsBeforeAnnotations() {
     if (_comment == null || _metadata.isEmpty) {
@@ -506,13 +506,13 @@
   }
 }
 /**
- * Instances of the class {@code Annotation} represent an annotation that can be associated with an
+ * Instances of the class `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}?
+ * '@' [Identifier qualified] ('.' [SimpleIdentifier identifier])? [ArgumentList arguments]?
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -530,19 +530,19 @@
   Identifier _name;
 
   /**
-   * The period before the constructor name, or {@code null} if this annotation is not the
+   * The period before the constructor name, or `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
+   * The name of the constructor being invoked, or `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
+   * The arguments to the constructor being invoked, or `null` if this annotation is not the
    * invocation of a constructor.
    */
   ArgumentList _arguments;
@@ -552,11 +552,11 @@
    * @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
+   * @param period the period before the constructor name, or `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
+   * @param constructorName the name of the constructor being invoked, or `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
+   * @param arguments the arguments to the constructor being invoked, or `null` if this
    * annotation is not the invocation of a constructor
    */
   Annotation.full(Token atSign, Identifier name, Token period, SimpleIdentifier constructorName, ArgumentList arguments) {
@@ -572,18 +572,18 @@
    * @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
+   * @param period the period before the constructor name, or `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
+   * @param constructorName the name of the constructor being invoked, or `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
+   * @param arguments the arguments to the constructor being invoked, or `null` if this
    * annotation is not the invocation of a constructor
    */
   Annotation({Token atSign, Identifier name, Token period, SimpleIdentifier constructorName, ArgumentList arguments}) : this.full(atSign, name, period, constructorName, arguments);
   accept(ASTVisitor visitor) => visitor.visitAnnotation(this);
 
   /**
-   * Return the arguments to the constructor being invoked, or {@code null} if this annotation is
+   * Return the arguments to the constructor being invoked, or `null` if this annotation is
    * not the invocation of a constructor.
    * @return the arguments to the constructor being invoked
    */
@@ -597,14 +597,14 @@
   Token get beginToken => _atSign;
 
   /**
-   * Return the name of the constructor being invoked, or {@code null} if this annotation is not the
+   * Return the name of the constructor being invoked, or `null` if this annotation is not the
    * invocation of a named constructor.
    * @return the name of the constructor being invoked
    */
   SimpleIdentifier get constructorName => _constructorName;
 
   /**
-   * Return the element associated with this annotation, or {@code null} if the AST structure has
+   * Return the element associated with this annotation, or `null` if the AST structure has
    * not been resolved or if this annotation could not be resolved.
    * @return the element associated with this annotation
    */
@@ -633,7 +633,7 @@
   Identifier get name => _name;
 
   /**
-   * Return the period before the constructor name, or {@code null} if this annotation is not the
+   * Return the period before the constructor name, or `null` if this annotation is not the
    * invocation of a named constructor.
    * @return the period before the constructor name
    */
@@ -686,10 +686,10 @@
   }
 }
 /**
- * Instances of the class {@code ArgumentDefinitionTest} represent an argument definition test.
+ * Instances of the class `ArgumentDefinitionTest` represent an argument definition test.
  * <pre>
  * argumentDefinitionTest ::=
- * '?' {@link SimpleIdentifier identifier}</pre>
+ * '?' [SimpleIdentifier identifier]</pre>
  * @coverage dart.engine.ast
  */
 class ArgumentDefinitionTest extends Expression {
@@ -756,13 +756,13 @@
   }
 }
 /**
- * Instances of the class {@code ArgumentList} represent a list of arguments in the invocation of a
+ * Instances of the class `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})
+ * arguments ::=[NamedExpression namedArgument] (',' [NamedExpression namedArgument])
+ * | [Expression expressionList] (',' [NamedExpression namedArgument])
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -785,18 +785,18 @@
 
   /**
    * An array containing the elements representing the parameters corresponding to each of the
-   * arguments in this list, or {@code null} if the AST has not been resolved or if the function or
+   * arguments in this list, or `null` if the AST has not been resolved or if the function or
    * method being invoked could not be determined based on static type information. The array must
-   * be the same length as the number of arguments, but can contain {@code null} entries if a given
+   * be the same length as the number of arguments, but can contain `null` entries if a given
    * argument does not correspond to a formal parameter.
    */
   List<ParameterElement> _correspondingStaticParameters;
 
   /**
    * An array containing the elements representing the parameters corresponding to each of the
-   * arguments in this list, or {@code null} if the AST has not been resolved or if the function or
+   * arguments in this list, or `null` if the AST has not been resolved or if the function or
    * method being invoked could not be determined based on propagated type information. The array
-   * must be the same length as the number of arguments, but can contain {@code null} entries if a
+   * must be the same length as the number of arguments, but can contain `null` entries if a
    * given argument does not correspond to a formal parameter.
    */
   List<ParameterElement> _correspondingPropagatedParameters;
@@ -848,7 +848,7 @@
   /**
    * Set the parameter elements corresponding to each of the arguments in this list to the given
    * array of parameters. The array of parameters must be the same length as the number of
-   * arguments, but can contain {@code null} entries if a given argument does not correspond to a
+   * arguments, but can contain `null` entries if a given argument does not correspond to a
    * formal parameter.
    * @param parameters the parameter elements corresponding to the arguments
    */
@@ -862,7 +862,7 @@
   /**
    * Set the parameter elements corresponding to each of the arguments in this list to the given
    * array of parameters. The array of parameters must be the same length as the number of
-   * arguments, but can contain {@code null} entries if a given argument does not correspond to a
+   * arguments, but can contain `null` entries if a given argument does not correspond to a
    * formal parameter.
    * @param parameters the parameter elements corresponding to the arguments
    */
@@ -897,9 +897,9 @@
    * the function being invoked is known based on propagated type information, and the expression
    * corresponds to one of the parameters of the function being invoked, then return the parameter
    * element representing the parameter to which the value of the given expression will be bound.
-   * Otherwise, return {@code null}.
-   * <p>
-   * This method is only intended to be used by {@link Expression#getParameterElement()}.
+   * Otherwise, return `null`.
+   *
+   * This method is only intended to be used by [Expression#getParameterElement].
    * @param expression the expression corresponding to the parameter to be returned
    * @return the parameter element representing the parameter to which the value of the expression
    * will be bound
@@ -920,9 +920,9 @@
    * the function being invoked is known based on static type information, and the expression
    * corresponds to one of the parameters of the function being invoked, then return the parameter
    * element representing the parameter to which the value of the given expression will be bound.
-   * Otherwise, return {@code null}.
-   * <p>
-   * This method is only intended to be used by {@link Expression#getStaticParameterElement()}.
+   * Otherwise, return `null`.
+   *
+   * This method is only intended to be used by [Expression#getStaticParameterElement].
    * @param expression the expression corresponding to the parameter to be returned
    * @return the parameter element representing the parameter to which the value of the expression
    * will be bound
@@ -939,9 +939,9 @@
   }
 }
 /**
- * Instances of the class {@code AsExpression} represent an 'as' expression.
+ * Instances of the class `AsExpression` represent an 'as' expression.
  * <pre>
- * asExpression ::={@link Expression expression} 'as' {@link TypeName type}</pre>
+ * asExpression ::=[Expression expression] 'as' [TypeName type]</pre>
  * @coverage dart.engine.ast
  */
 class AsExpression extends Expression {
@@ -1031,10 +1031,10 @@
   }
 }
 /**
- * Instances of the class {@code AssertStatement} represent an assert statement.
+ * Instances of the class `AssertStatement` represent an assert statement.
  * <pre>
  * assertStatement ::=
- * 'assert' '(' {@link Expression conditionalExpression} ')' ';'
+ * 'assert' '(' [Expression conditionalExpression] ')' ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -1051,7 +1051,7 @@
   Token _leftParenthesis;
 
   /**
-   * The condition that is being asserted to be {@code true}.
+   * The condition that is being asserted to be `true`.
    */
   Expression _condition;
 
@@ -1069,7 +1069,7 @@
    * 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 condition the condition that is being asserted to be `true`
    * @param rightParenthesis the right parenthesis
    * @param semicolon the semicolon terminating the statement
    */
@@ -1085,7 +1085,7 @@
    * 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 condition the condition that is being asserted to be `true`
    * @param rightParenthesis the right parenthesis
    * @param semicolon the semicolon terminating the statement
    */
@@ -1094,8 +1094,8 @@
   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}
+   * Return the condition that is being asserted to be `true`.
+   * @return the condition that is being asserted to be `true`
    */
   Expression get condition => _condition;
   Token get endToken => _semicolon;
@@ -1125,8 +1125,8 @@
   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}
+   * Set the condition that is being asserted to be `true` to the given expression.
+   * @param the condition that is being asserted to be `true`
    */
   void set condition(Expression condition2) {
     this._condition = becomeParentOf(condition2);
@@ -1168,9 +1168,9 @@
   }
 }
 /**
- * Instances of the class {@code AssignmentExpression} represent an assignment expression.
+ * Instances of the class `AssignmentExpression` represent an assignment expression.
  * <pre>
- * assignmentExpression ::={@link Expression leftHandSide} {@link Token operator} {@link Expression rightHandSide}</pre>
+ * assignmentExpression ::=[Expression leftHandSide] [Token operator] [Expression rightHandSide]</pre>
  * @coverage dart.engine.ast
  */
 class AssignmentExpression extends Expression {
@@ -1191,13 +1191,13 @@
   Expression _rightHandSide;
 
   /**
-   * The element associated with the operator based on the static type of the left-hand-side, or{@code null} if the AST structure has not been resolved, if the operator is not a compound
+   * The element associated with the operator based on the static type of the left-hand-side, or`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 _staticElement;
 
   /**
-   * The element associated with the operator based on the propagated type of the left-hand-side, or{@code null} if the AST structure has not been resolved, if the operator is not a compound
+   * The element associated with the operator based on the propagated type of the left-hand-side, or`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 _propagatedElement;
@@ -1226,7 +1226,7 @@
 
   /**
    * Return the element associated with the operator based on the propagated type of the
-   * left-hand-side, or {@code null} if the AST structure has not been resolved, if the operator is
+   * left-hand-side, or `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
@@ -1254,7 +1254,7 @@
 
   /**
    * Return the element associated with the operator based on the static type of the left-hand-side,
-   * or {@code null} if the AST structure has not been resolved, if the operator is not a compound
+   * or `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
@@ -1308,9 +1308,9 @@
   }
 }
 /**
- * Instances of the class {@code BinaryExpression} represent a binary (infix) expression.
+ * Instances of the class `BinaryExpression` represent a binary (infix) expression.
  * <pre>
- * binaryExpression ::={@link Expression leftOperand} {@link Token operator} {@link Expression rightOperand}</pre>
+ * binaryExpression ::=[Expression leftOperand] [Token operator] [Expression rightOperand]</pre>
  * @coverage dart.engine.ast
  */
 class BinaryExpression extends Expression {
@@ -1331,13 +1331,13 @@
   Expression _rightOperand;
 
   /**
-   * The element associated with the operator based on the static type of the left operand, or{@code null} if the AST structure has not been resolved, if the operator is not user definable,
+   * The element associated with the operator based on the static type of the left operand, or`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 _staticElement;
 
   /**
-   * The element associated with the operator based on the propagated type of the left operand, or{@code null} if the AST structure has not been resolved, if the operator is not user definable,
+   * The element associated with the operator based on the propagated type of the left operand, or`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 _propagatedElement;
@@ -1366,7 +1366,7 @@
 
   /**
    * Return the element associated with the operator based on the propagated type of the left
-   * operand, or {@code null} if the AST structure has not been resolved, if the operator is not
+   * operand, or `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
@@ -1394,7 +1394,7 @@
 
   /**
    * Return the element associated with the operator based on the static type of the left operand,
-   * or {@code null} if the AST structure has not been resolved, if the operator is not user
+   * or `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 operand.
    * @return the element associated with the operator
@@ -1450,9 +1450,9 @@
   /**
    * If the AST structure has been resolved, and the function being invoked is known based on
    * propagated type information, then return the parameter element representing the parameter to
-   * which the value of the right operand will be bound. Otherwise, return {@code null}.
-   * <p>
-   * This method is only intended to be used by {@link Expression#getParameterElement()}.
+   * which the value of the right operand will be bound. Otherwise, return `null`.
+   *
+   * This method is only intended to be used by [Expression#getParameterElement].
    * @return the parameter element representing the parameter to which the value of the right
    * operand will be bound
    */
@@ -1470,9 +1470,9 @@
   /**
    * If the AST structure has been resolved, and the function being invoked is known based on static
    * type information, then return the parameter element representing the parameter to which the
-   * value of the right operand will be bound. Otherwise, return {@code null}.
-   * <p>
-   * This method is only intended to be used by {@link Expression#getStaticParameterElement()}.
+   * value of the right operand will be bound. Otherwise, return `null`.
+   *
+   * This method is only intended to be used by [Expression#getStaticParameterElement].
    * @return the parameter element representing the parameter to which the value of the right
    * operand will be bound
    */
@@ -1488,7 +1488,7 @@
   }
 }
 /**
- * Instances of the class {@code Block} represent a sequence of statements.
+ * Instances of the class `Block` represent a sequence of statements.
  * <pre>
  * block ::=
  * '{' statement* '}'
@@ -1574,10 +1574,10 @@
   }
 }
 /**
- * Instances of the class {@code BlockFunctionBody} represent a function body that consists of a
+ * Instances of the class `BlockFunctionBody` represent a function body that consists of a
  * block of statements.
  * <pre>
- * blockFunctionBody ::={@link Block block}</pre>
+ * blockFunctionBody ::=[Block block]</pre>
  * @coverage dart.engine.ast
  */
 class BlockFunctionBody extends FunctionBody {
@@ -1622,7 +1622,7 @@
   }
 }
 /**
- * Instances of the class {@code BooleanLiteral} represent a boolean literal expression.
+ * Instances of the class `BooleanLiteral` represent a boolean literal expression.
  * <pre>
  * booleanLiteral ::=
  * 'false' | 'true'
@@ -1672,7 +1672,7 @@
    * @return the value of the literal
    */
   bool get value => _value;
-  bool isSynthetic() => _literal.isSynthetic();
+  bool get isSynthetic => _literal.isSynthetic;
 
   /**
    * Set the token representing the literal to the given token.
@@ -1693,10 +1693,10 @@
   }
 }
 /**
- * Instances of the class {@code BreakStatement} represent a break statement.
+ * Instances of the class `BreakStatement` represent a break statement.
  * <pre>
  * breakStatement ::=
- * 'break' {@link SimpleIdentifier label}? ';'
+ * 'break' [SimpleIdentifier label]? ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -1708,7 +1708,7 @@
   Token _keyword;
 
   /**
-   * The label associated with the statement, or {@code null} if there is no label.
+   * The label associated with the statement, or `null` if there is no label.
    */
   SimpleIdentifier _label;
 
@@ -1747,7 +1747,7 @@
   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, or `null` if there is no label.
    * @return the label associated with the statement
    */
   SimpleIdentifier get label => _label;
@@ -1786,11 +1786,11 @@
   }
 }
 /**
- * Instances of the class {@code CascadeExpression} represent a sequence of cascaded expressions:
+ * Instances of the class `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}.
+ * a cascade expression: [IndexExpression], [MethodInvocation] and[PropertyAccess].
  * <pre>
- * cascadeExpression ::={@link Expression conditionalExpression} cascadeSection
+ * cascadeExpression ::=[Expression conditionalExpression] cascadeSection
  * cascadeSection ::=
  * '..'  (cascadeSelector arguments*) (assignableSelector arguments*)* (assignmentOperator expressionWithoutCascade)?
  * cascadeSelector ::=
@@ -1857,29 +1857,29 @@
   }
 }
 /**
- * Instances of the class {@code CatchClause} represent a catch clause within a try statement.
+ * Instances of the class `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})? ')'
+ * catchPart [Block block]| 'on' type catchPart? [Block block]catchPart ::=
+ * 'catch' '(' [SimpleIdentifier exceptionParameter] (',' [SimpleIdentifier stackTraceParameter])? ')'
  * </pre>
  * @coverage dart.engine.ast
  */
 class CatchClause extends ASTNode {
 
   /**
-   * The token representing the 'on' keyword, or {@code null} if there is no 'on' keyword.
+   * The token representing the 'on' keyword, or `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
+   * The type of exceptions caught by this catch clause, or `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.
+   * The token representing the 'catch' keyword, or `null` if there is no 'catch' keyword.
    */
   Token _catchKeyword;
 
@@ -1965,7 +1965,7 @@
   Block get body => _body;
 
   /**
-   * Return the token representing the 'catch' keyword, or {@code null} if there is no 'catch'
+   * Return the token representing the 'catch' keyword, or `null` if there is no 'catch'
    * keyword.
    * @return the token representing the 'catch' keyword
    */
@@ -1985,7 +1985,7 @@
   SimpleIdentifier get exceptionParameter => _exceptionParameter;
 
   /**
-   * Return the type of exceptions caught by this catch clause, or {@code null} if this catch clause
+   * Return the type of exceptions caught by this catch clause, or `null` if this catch clause
    * catches every type of exception.
    * @return the type of exceptions caught by this catch clause
    */
@@ -1998,7 +1998,7 @@
   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, or `null` if there is no 'on' keyword.
    * @return the token representing the 'on' keyword
    */
   Token get onKeyword => _onKeyword;
@@ -2096,19 +2096,19 @@
   }
 }
 /**
- * Instances of the class {@code ClassDeclaration} represent the declaration of a class.
+ * Instances of the class `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}* '}'
+ * 'abstract'? 'class' [SimpleIdentifier name] [TypeParameterList typeParameterList]?
+ * ([ExtendsClause extendsClause] [WithClause withClause]?)?[ImplementsClause implementsClause]?
+ * '{' [ClassMember classMember]* '}'
  * </pre>
  * @coverage dart.engine.ast
  */
 class ClassDeclaration extends CompilationUnitMember {
 
   /**
-   * The 'abstract' keyword, or {@code null} if the keyword was absent.
+   * The 'abstract' keyword, or `null` if the keyword was absent.
    */
   Token _abstractKeyword;
 
@@ -2123,23 +2123,23 @@
   SimpleIdentifier _name;
 
   /**
-   * The type parameters for the class, or {@code null} if the class does not have any type
+   * The type parameters for the class, or `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.
+   * The extends clause for the class, or `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.
+   * The with clause for the class, or `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
+   * The implements clause for the class, or `null` if the class does not implement any
    * interfaces.
    */
   ImplementsClause _implementsClause;
@@ -2163,7 +2163,7 @@
    * 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 abstractKeyword the 'abstract' keyword, or `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
@@ -2192,7 +2192,7 @@
    * 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 abstractKeyword the 'abstract' keyword, or `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
@@ -2207,7 +2207,7 @@
   accept(ASTVisitor visitor) => visitor.visitClassDeclaration(this);
 
   /**
-   * Return the 'abstract' keyword, or {@code null} if the keyword was absent.
+   * Return the 'abstract' keyword, or `null` if the keyword was absent.
    * @return the 'abstract' keyword
    */
   Token get abstractKeyword => _abstractKeyword;
@@ -2221,14 +2221,14 @@
   Token get endToken => _rightBracket;
 
   /**
-   * Return the extends clause for this class, or {@code null} if the class does not extend any
+   * Return the extends clause for this class, or `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
+   * Return the implements clause for the class, or `null` if the class does not implement any
    * interfaces.
    * @return the implements clause for the class
    */
@@ -2259,14 +2259,14 @@
   Token get rightBracket => _rightBracket;
 
   /**
-   * Return the type parameters for the class, or {@code null} if the class does not have any type
+   * Return the type parameters for the class, or `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, or `null` if the class does not have a with clause.
    * @return the with clause for the class
    */
   WithClause get withClause => _withClause;
@@ -2359,7 +2359,7 @@
   }
 }
 /**
- * The abstract class {@code ClassMember} defines the behavior common to nodes that declare a name
+ * The abstract class `ClassMember` defines the behavior common to nodes that declare a name
  * within the scope of a class.
  * @coverage dart.engine.ast
  */
@@ -2381,10 +2381,10 @@
   ClassMember({Comment comment, List<Annotation> metadata}) : this.full(comment, metadata);
 }
 /**
- * Instances of the class {@code ClassTypeAlias} represent a class type alias.
+ * Instances of the class `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}? ';'
+ * classTypeAlias ::=[SimpleIdentifier identifier] [TypeParameterList typeParameters]? '=' 'abstract'? mixinApplication
+ * mixinApplication ::=[TypeName superclass] [WithClause withClause] [ImplementsClause implementsClause]? ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -2396,7 +2396,7 @@
   SimpleIdentifier _name;
 
   /**
-   * The type parameters for the class, or {@code null} if the class does not have any type
+   * The type parameters for the class, or `null` if the class does not have any type
    * parameters.
    */
   TypeParameterList _typeParameters;
@@ -2407,7 +2407,7 @@
   Token _equals;
 
   /**
-   * The token for the 'abstract' keyword, or {@code null} if this is not defining an abstract
+   * The token for the 'abstract' keyword, or `null` if this is not defining an abstract
    * class.
    */
   Token _abstractKeyword;
@@ -2423,7 +2423,7 @@
   WithClause _withClause;
 
   /**
-   * The implements clause for this class, or {@code null} if there is no implements clause.
+   * The implements clause for this class, or `null` if there is no implements clause.
    */
   ImplementsClause _implementsClause;
 
@@ -2469,7 +2469,7 @@
   accept(ASTVisitor visitor) => visitor.visitClassTypeAlias(this);
 
   /**
-   * Return the token for the 'abstract' keyword, or {@code null} if this is not defining an
+   * Return the token for the 'abstract' keyword, or `null` if this is not defining an
    * abstract class.
    * @return the token for the 'abstract' keyword
    */
@@ -2483,7 +2483,7 @@
   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, or `null` if there is no implements clause.
    * @return the implements clause for this class
    */
   ImplementsClause get implementsClause => _implementsClause;
@@ -2501,7 +2501,7 @@
   TypeName get superclass => _superclass;
 
   /**
-   * Return the type parameters for the class, or {@code null} if the class does not have any type
+   * Return the type parameters for the class, or `null` if the class does not have any type
    * parameters.
    * @return the type parameters for the class
    */
@@ -2578,10 +2578,10 @@
   }
 }
 /**
- * Instances of the class {@code Combinator} represent the combinator associated with an import
+ * Instances of the class `Combinator` represent the combinator associated with an import
  * directive.
  * <pre>
- * combinator ::={@link HideCombinator hideCombinator}| {@link ShowCombinator showCombinator}</pre>
+ * combinator ::=[HideCombinator hideCombinator]| [ShowCombinator showCombinator]</pre>
  * @coverage dart.engine.ast
  */
 abstract class Combinator extends ASTNode {
@@ -2625,7 +2625,7 @@
   }
 }
 /**
- * Instances of the class {@code Comment} represent a comment within the source code.
+ * Instances of the class `Comment` represent a comment within the source code.
  * <pre>
  * comment ::=
  * endOfLineComment
@@ -2636,7 +2636,7 @@
  * blockComment ::=
  * '/ *' CHARACTER* '&#42;/'
  * documentationComment ::=
- * '/ **' (CHARACTER | {@link CommentReference commentReference})* '&#42;/'
+ * '/ **' (CHARACTER | [CommentReference commentReference])* '&#42;/'
  * | ('///' (CHARACTER - EOL)* EOL)+
  * </pre>
  * @coverage dart.engine.ast
@@ -2725,28 +2725,28 @@
   List<Token> get tokens => _tokens;
 
   /**
-   * Return {@code true} if this is a block comment.
-   * @return {@code true} if this is a block comment
+   * Return `true` if this is a block comment.
+   * @return `true` if this is a block comment
    */
-  bool isBlock() => identical(_type, CommentType.BLOCK);
+  bool get isBlock => identical(_type, CommentType.BLOCK);
 
   /**
-   * Return {@code true} if this is a documentation comment.
-   * @return {@code true} if this is a documentation comment
+   * Return `true` if this is a documentation comment.
+   * @return `true` if this is a documentation comment
    */
-  bool isDocumentation() => identical(_type, CommentType.DOCUMENTATION);
+  bool get isDocumentation => identical(_type, CommentType.DOCUMENTATION);
 
   /**
-   * Return {@code true} if this is an end-of-line comment.
-   * @return {@code true} if this is an end-of-line comment
+   * Return `true` if this is an end-of-line comment.
+   * @return `true` if this is an end-of-line comment
    */
-  bool isEndOfLine() => identical(_type, CommentType.END_OF_LINE);
+  bool get isEndOfLine => identical(_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
+ * The enumeration `CommentType` encodes all the different types of comments that are
  * recognized by the parser.
  */
 class CommentType implements Comparable<CommentType> {
@@ -2779,18 +2779,18 @@
   String toString() => name;
 }
 /**
- * Instances of the class {@code CommentReference} represent a reference to a Dart element that is
+ * Instances of the class `CommentReference` represent a reference to a Dart element that is
  * found within a documentation comment.
  * <pre>
  * commentReference ::=
- * '\[' 'new'? {@link Identifier identifier} '\]'
+ * '\[' 'new'? [Identifier identifier] '\]'
  * </pre>
  * @coverage dart.engine.ast
  */
 class CommentReference extends ASTNode {
 
   /**
-   * The token representing the 'new' keyword, or {@code null} if there was no 'new' keyword.
+   * The token representing the 'new' keyword, or `null` if there was no 'new' keyword.
    */
   Token _newKeyword;
 
@@ -2826,7 +2826,7 @@
   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, or `null` if there was no 'new' keyword.
    * @return the token representing the 'new' keyword
    */
   Token get newKeyword => _newKeyword;
@@ -2851,8 +2851,8 @@
   }
 }
 /**
- * Instances of the class {@code CompilationUnit} represent a compilation unit.
- * <p>
+ * Instances of the class `CompilationUnit` represent a compilation unit.
+ *
  * 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
@@ -2860,7 +2860,7 @@
  * <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>
+ * directives ::=[ScriptTag scriptTag]? [LibraryDirective libraryDirective]? namespaceDirective* [PartDirective partDirective]| [PartOfDirective partOfDirective]namespaceDirective ::=[ImportDirective importDirective]| [ExportDirective exportDirective]declarations ::=[CompilationUnitMember compilationUnitMember]</pre>
  * @coverage dart.engine.ast
  */
 class CompilationUnit extends ASTNode {
@@ -2871,7 +2871,7 @@
   Token _beginToken;
 
   /**
-   * The script tag at the beginning of the compilation unit, or {@code null} if there is no script
+   * The script tag at the beginning of the compilation unit, or `null` if there is no script
    * tag in this compilation unit.
    */
   ScriptTag _scriptTag;
@@ -2888,18 +2888,18 @@
 
   /**
    * 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}.
+   * should always have a type of [TokenType.EOF].
    */
   Token _endToken;
 
   /**
-   * The element associated with this compilation unit, or {@code null} if the AST structure has not
+   * The element associated with this compilation unit, or `null` if the AST structure has not
    * been resolved.
    */
   CompilationUnitElement _element;
 
   /**
-   * The {@link LineInfo} for this {@link CompilationUnit}.
+   * The [LineInfo] for this [CompilationUnit].
    */
   LineInfo _lineInfo;
 
@@ -2956,7 +2956,7 @@
   NodeList<Directive> get directives => _directives;
 
   /**
-   * Return the element associated with this compilation unit, or {@code null} if the AST structure
+   * Return the element associated with this compilation unit, or `null` if the AST structure
    * has not been resolved.
    * @return the element associated with this compilation unit
    */
@@ -2965,8 +2965,8 @@
 
   /**
    * 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
+   * not been resolved, then return `null`.
+   * @return an array of errors (contains no `null`s) or `null` if the receiver has not
    * been resolved
    */
   List<AnalysisError> get errors {
@@ -2992,28 +2992,28 @@
   }
 
   /**
-   * Get the {@link LineInfo} object for this compilation unit.
-   * @return the associated {@link LineInfo}
+   * Get the [LineInfo] object for this compilation unit.
+   * @return the associated [LineInfo]
    */
   LineInfo get lineInfo => _lineInfo;
   int get offset => 0;
 
   /**
    * Return an array containing all of the parsing errors associated with the receiver.
-   * @return an array of errors (not {@code null}, contains no {@code null}s).
+   * @return an array of errors (not `null`, contains no `null`s).
    */
   List<AnalysisError> get parsingErrors => _parsingErrors;
 
   /**
    * Return an array containing all of the resolution errors associated with the receiver. If the
-   * receiver has not been resolved, then return {@code null}.
-   * @return an array of errors (contains no {@code null}s) or {@code null} if the receiver has not
+   * receiver has not been resolved, then return `null`.
+   * @return an array of errors (contains no `null`s) or `null` if the receiver has not
    * been resolved
    */
   List<AnalysisError> get resolutionErrors => _resolutionErrors;
 
   /**
-   * Return the script tag at the beginning of the compilation unit, or {@code null} if there is no
+   * Return the script tag at the beginning of the compilation unit, or `null` if there is no
    * script tag in this compilation unit.
    * @return the script tag at the beginning of the compilation unit
    */
@@ -3028,7 +3028,7 @@
   }
 
   /**
-   * Set the {@link LineInfo} object for this compilation unit.
+   * Set the [LineInfo] object for this compilation unit.
    * @param errors LineInfo to associate with this compilation unit
    */
   void set lineInfo(LineInfo lineInfo2) {
@@ -3037,8 +3037,8 @@
 
   /**
    * Called to cache the parsing errors when the unit is parsed.
-   * @param errors an array of parsing errors, if {@code null} is passed, the error array is set to
-   * an empty array, {@link AnalysisError#NO_ERRORS}
+   * @param errors an array of parsing errors, if `null` is passed, the error array is set to
+   * an empty array, [AnalysisError#NO_ERRORS]
    */
   void set parsingErrors(List<AnalysisError> errors) {
     _parsingErrors = errors == null ? AnalysisError.NO_ERRORS : errors;
@@ -3046,8 +3046,8 @@
 
   /**
    * Called to cache the resolution errors when the unit is resolved.
-   * @param errors an array of resolution errors, if {@code null} is passed, the error array is set
-   * to an empty array, {@link AnalysisError#NO_ERRORS}
+   * @param errors an array of resolution errors, if `null` is passed, the error array is set
+   * to an empty array, [AnalysisError#NO_ERRORS]
    */
   void set resolutionErrors(List<AnalysisError> errors) {
     _resolutionErrors = errors == null ? AnalysisError.NO_ERRORS : errors;
@@ -3073,8 +3073,8 @@
   }
 
   /**
-   * 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
+   * Return `true` if all of the directives are lexically before any declarations.
+   * @return `true` if all of the directives are lexically before any declarations
    */
   bool directivesAreBeforeDeclarations() {
     if (_directives.isEmpty || _declarations.isEmpty) {
@@ -3101,10 +3101,10 @@
   }
 }
 /**
- * Instances of the class {@code CompilationUnitMember} defines the behavior common to nodes that
+ * Instances of the class `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>
+ * compilationUnitMember ::=[ClassDeclaration classDeclaration]| [TypeAlias typeAlias]| [FunctionDeclaration functionDeclaration]| [MethodDeclaration getOrSetDeclaration]| [VariableDeclaration constantsDeclaration]| [VariableDeclaration variablesDeclaration]</pre>
  * @coverage dart.engine.ast
  */
 abstract class CompilationUnitMember extends Declaration {
@@ -3125,9 +3125,9 @@
   CompilationUnitMember({Comment comment, List<Annotation> metadata}) : this.full(comment, metadata);
 }
 /**
- * Instances of the class {@code ConditionalExpression} represent a conditional expression.
+ * Instances of the class `ConditionalExpression` represent a conditional expression.
  * <pre>
- * conditionalExpression ::={@link Expression condition} '?' {@link Expression thenExpression} ':' {@link Expression elseExpression}</pre>
+ * conditionalExpression ::=[Expression condition] '?' [Expression thenExpression] ':' [Expression elseExpression]</pre>
  * @coverage dart.engine.ast
  */
 class ConditionalExpression extends Expression {
@@ -3143,7 +3143,7 @@
   Token _question;
 
   /**
-   * The expression that is executed if the condition evaluates to {@code true}.
+   * The expression that is executed if the condition evaluates to `true`.
    */
   Expression _thenExpression;
 
@@ -3153,7 +3153,7 @@
   Token _colon;
 
   /**
-   * The expression that is executed if the condition evaluates to {@code false}.
+   * The expression that is executed if the condition evaluates to `false`.
    */
   Expression _elseExpression;
 
@@ -3161,9 +3161,9 @@
    * 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 thenExpression the expression that is executed if the condition evaluates to`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}
+   * @param elseExpression the expression that is executed if the condition evaluates to`false`
    */
   ConditionalExpression.full(Expression condition, Token question, Expression thenExpression, Token colon, Expression elseExpression) {
     this._condition = becomeParentOf(condition);
@@ -3177,9 +3177,9 @@
    * 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 thenExpression the expression that is executed if the condition evaluates to`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}
+   * @param elseExpression the expression that is executed if the condition evaluates to`false`
    */
   ConditionalExpression({Expression condition, Token question, Expression thenExpression, Token colon, Expression elseExpression}) : this.full(condition, question, thenExpression, colon, elseExpression);
   accept(ASTVisitor visitor) => visitor.visitConditionalExpression(this);
@@ -3198,8 +3198,8 @@
   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}
+   * Return the expression that is executed if the condition evaluates to `false`.
+   * @return the expression that is executed if the condition evaluates to `false`
    */
   Expression get elseExpression => _elseExpression;
   Token get endToken => _elseExpression.endToken;
@@ -3211,8 +3211,8 @@
   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}
+   * Return the expression that is executed if the condition evaluates to `true`.
+   * @return the expression that is executed if the condition evaluates to `true`
    */
   Expression get thenExpression => _thenExpression;
 
@@ -3234,9 +3234,9 @@
   }
 
   /**
-   * Set the expression that is executed if the condition evaluates to {@code false} to the given
+   * Set the expression that is executed if the condition evaluates to `false` to the given
    * expression.
-   * @param expression the expression that is executed if the condition evaluates to {@code false}
+   * @param expression the expression that is executed if the condition evaluates to `false`
    */
   void set elseExpression(Expression expression) {
     _elseExpression = becomeParentOf(expression);
@@ -3251,9 +3251,9 @@
   }
 
   /**
-   * Set the expression that is executed if the condition evaluates to {@code true} to the given
+   * Set the expression that is executed if the condition evaluates to `true` to the given
    * expression.
-   * @param expression the expression that is executed if the condition evaluates to {@code true}
+   * @param expression the expression that is executed if the condition evaluates to `true`
    */
   void set thenExpression(Expression expression) {
     _thenExpression = becomeParentOf(expression);
@@ -3265,37 +3265,37 @@
   }
 }
 /**
- * Instances of the class {@code ConstructorDeclaration} represent a constructor declaration.
+ * Instances of the class `ConstructorDeclaration` represent a constructor declaration.
  * <pre>
  * constructorDeclaration ::=
- * constructorSignature {@link FunctionBody body}?
- * | constructorName formalParameterList ':' 'this' ('.' {@link SimpleIdentifier name})? arguments
+ * constructorSignature [FunctionBody body]?
+ * | constructorName formalParameterList ':' 'this' ('.' [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})?
+ * constructorName ::=[SimpleIdentifier returnType] ('.' [SimpleIdentifier name])?
+ * factoryName ::=[Identifier returnType] ('.' [SimpleIdentifier name])?
  * initializerList ::=
- * ':' {@link ConstructorInitializer initializer} (',' {@link ConstructorInitializer initializer})
+ * ':' [ConstructorInitializer initializer] (',' [ConstructorInitializer initializer])
  * </pre>
  * @coverage dart.engine.ast
  */
 class ConstructorDeclaration extends ClassMember {
 
   /**
-   * The token for the 'external' keyword, or {@code null} if the constructor is not external.
+   * The token for the 'external' keyword, or `null` if the constructor is not external.
    */
   Token _externalKeyword;
 
   /**
-   * The token for the 'const' keyword, or {@code null} if the constructor is not a const
+   * The token for the 'const' keyword, or `null` if the constructor is not a const
    * constructor.
    */
   Token _constKeyword;
 
   /**
-   * The token for the 'factory' keyword, or {@code null} if the constructor is not a factory
+   * The token for the 'factory' keyword, or `null` if the constructor is not a factory
    * constructor.
    */
   Token _factoryKeyword;
@@ -3307,18 +3307,18 @@
   Identifier _returnType;
 
   /**
-   * The token for the period before the constructor name, or {@code null} if the constructor being
+   * The token for the period before the constructor name, or `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.
+   * The name of the constructor, or `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
+   * The element associated with this constructor, or `null` if the AST structure has not been
    * resolved or if this constructor could not be resolved.
    */
   ConstructorElement _element;
@@ -3329,7 +3329,7 @@
   FormalParameterList _parameters;
 
   /**
-   * The token for the separator (colon or equals) before the initializers, or {@code null} if there
+   * The token for the separator (colon or equals) before the initializers, or `null` if there
    * are no initializers.
    */
   Token _separator;
@@ -3340,13 +3340,13 @@
   NodeList<ConstructorInitializer> _initializers;
 
   /**
-   * The name of the constructor to which this constructor will be redirected, or {@code null} if
+   * The name of the constructor to which this constructor will be redirected, or `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.
+   * The body of the constructor, or `null` if the constructor does not have a body.
    */
   FunctionBody _body;
 
@@ -3403,7 +3403,7 @@
   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, or `null` if the constructor does not have a body.
    * @return the body of the constructor
    */
   FunctionBody get body => _body;
@@ -3424,7 +3424,7 @@
   }
 
   /**
-   * Return the token for the 'external' keyword, or {@code null} if the constructor is not
+   * Return the token for the 'external' keyword, or `null` if the constructor is not
    * external.
    * @return the token for the 'external' keyword
    */
@@ -3443,7 +3443,7 @@
   NodeList<ConstructorInitializer> get initializers => _initializers;
 
   /**
-   * Return the name of the constructor, or {@code null} if the constructor being declared is
+   * Return the name of the constructor, or `null` if the constructor being declared is
    * unnamed.
    * @return the name of the constructor
    */
@@ -3456,14 +3456,14 @@
   FormalParameterList get parameters => _parameters;
 
   /**
-   * Return the token for the period before the constructor name, or {@code null} if the constructor
+   * Return the token for the period before the constructor name, or `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, or`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;
@@ -3477,7 +3477,7 @@
   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, or `null`if there are no initializers.
    * @return the token for the separator (colon or equals) before the initializers
    */
   Token get separator => _separator;
@@ -3589,8 +3589,8 @@
   }
 
   /**
-   * 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}.
+   * Return the left-most of the given tokens, or `null` if there are no tokens given or if
+   * all of the given tokens are `null`.
    * @param tokens the tokens being compared to find the left-most token
    * @return the left-most of the given tokens
    */
@@ -3606,22 +3606,22 @@
   }
 }
 /**
- * Instances of the class {@code ConstructorFieldInitializer} represent the initialization of a
+ * Instances of the class `ConstructorFieldInitializer` represent the initialization of a
  * field within a constructor's initialization list.
  * <pre>
  * fieldInitializer ::=
- * ('this' '.')? {@link SimpleIdentifier fieldName} '=' {@link Expression conditionalExpression cascadeSection*}</pre>
+ * ('this' '.')? [SimpleIdentifier fieldName] '=' [Expression conditionalExpression cascadeSection*]</pre>
  * @coverage dart.engine.ast
  */
 class ConstructorFieldInitializer extends ConstructorInitializer {
 
   /**
-   * The token for the 'this' keyword, or {@code null} if there is no 'this' keyword.
+   * The token for the 'this' keyword, or `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'
+   * The token for the period after the 'this' keyword, or `null` if there is no 'this'
    * keyword.
    */
   Token _period;
@@ -3696,13 +3696,13 @@
   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, or `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'
+   * Return the token for the period after the 'this' keyword, or `null` if there is no 'this'
    * keyword.
    * @return the token for the period after the 'this' keyword
    */
@@ -3754,16 +3754,16 @@
   }
 }
 /**
- * Instances of the class {@code ConstructorInitializer} defines the behavior of nodes that can
+ * Instances of the class `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>
+ * constructorInitializer ::=[SuperConstructorInvocation superInvocation]| [ConstructorFieldInitializer fieldInitializer]</pre>
  * @coverage dart.engine.ast
  */
 abstract class ConstructorInitializer extends ASTNode {
 }
 /**
- * Instances of the class {@code ConstructorName} represent the name of the constructor.
+ * Instances of the class `ConstructorName` represent the name of the constructor.
  * <pre>
  * constructorName:
  * type ('.' identifier)?
@@ -3778,25 +3778,25 @@
   TypeName _type;
 
   /**
-   * The token for the period before the constructor name, or {@code null} if the specified
+   * The token for the period before the constructor name, or `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
+   * The name of the constructor, or `null` if the specified constructor is the unnamed
    * constructor.
    */
   SimpleIdentifier _name;
 
   /**
-   * The element associated with this constructor name based on static type information, or{@code null} if the AST structure has not been resolved or if this constructor name could not
+   * The element associated with this constructor name based on static type information, or`null` if the AST structure has not been resolved or if this constructor name could not
    * be resolved.
    */
   ConstructorElement _staticElement;
 
   /**
-   * The element associated with this constructor name based on propagated type information, or{@code null} if the AST structure has not been resolved or if this constructor name could not
+   * The element associated with this constructor name based on propagated type information, or`null` if the AST structure has not been resolved or if this constructor name could not
    * be resolved.
    */
   ConstructorElement _propagatedElement;
@@ -3825,7 +3825,7 @@
 
   /**
    * Return the element associated with this constructor name based on propagated type information,
-   * or {@code null} if the AST structure has not been resolved or if this constructor name could
+   * or `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
    */
@@ -3838,21 +3838,21 @@
   }
 
   /**
-   * Return the name of the constructor, or {@code null} if the specified constructor is the unnamed
+   * Return the name of the constructor, or `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
+   * Return the token for the period before the constructor name, or `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 element associated with this constructor name based on static type information, or{@code null} if the AST structure has not been resolved or if this constructor name could not
+   * Return the element associated with this constructor name based on static type information, or`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
    */
@@ -3911,10 +3911,10 @@
   }
 }
 /**
- * Instances of the class {@code ContinueStatement} represent a continue statement.
+ * Instances of the class `ContinueStatement` represent a continue statement.
  * <pre>
  * continueStatement ::=
- * 'continue' {@link SimpleIdentifier label}? ';'
+ * 'continue' [SimpleIdentifier label]? ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -3926,7 +3926,7 @@
   Token _keyword;
 
   /**
-   * The label associated with the statement, or {@code null} if there is no label.
+   * The label associated with the statement, or `null` if there is no label.
    */
   SimpleIdentifier _label;
 
@@ -3965,7 +3965,7 @@
   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, or `null` if there is no label.
    * @return the label associated with the statement
    */
   SimpleIdentifier get label => _label;
@@ -4004,7 +4004,7 @@
   }
 }
 /**
- * The abstract class {@code Declaration} defines the behavior common to nodes that represent the
+ * The abstract class `Declaration` defines the behavior common to nodes that represent the
  * declaration of a name. Each declared name is visible within a name scope.
  * @coverage dart.engine.ast
  */
@@ -4026,30 +4026,30 @@
   Declaration({Comment comment, List<Annotation> metadata}) : this.full(comment, metadata);
 
   /**
-   * Return the element associated with this declaration, or {@code null} if either this node
+   * Return the element associated with this declaration, or `null` if either this node
    * corresponds to a list of declarations or if the AST structure has not been resolved.
    * @return the element associated with this declaration
    */
   Element get element;
 }
 /**
- * Instances of the class {@code DeclaredIdentifier} represent the declaration of a single
+ * Instances of the class `DeclaredIdentifier` represent the declaration of a single
  * identifier.
  * <pre>
  * declaredIdentifier ::=
- * ({@link Annotation metadata} finalConstVarOrType {@link SimpleIdentifier identifier}</pre>
+ * ([Annotation metadata] finalConstVarOrType [SimpleIdentifier identifier]</pre>
  * @coverage dart.engine.ast
  */
 class DeclaredIdentifier extends Declaration {
 
   /**
-   * The token representing either the 'final', 'const' or 'var' keyword, or {@code null} if no
+   * The token representing either the 'final', 'const' or 'var' keyword, or `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
+   * The name of the declared type of the parameter, or `null` if the parameter does not have
    * a declared type.
    */
   TypeName _type;
@@ -4105,25 +4105,25 @@
   Token get keyword => _keyword;
 
   /**
-   * Return the name of the declared type of the parameter, or {@code null} if the parameter does
+   * Return the name of the declared type of the parameter, or `null` if the parameter does
    * not have a declared type.
    * @return the name of the declared type of the parameter
    */
   TypeName get type => _type;
 
   /**
-   * Return {@code true} if this variable was declared with the 'const' modifier.
-   * @return {@code true} if this variable was declared with the 'const' modifier
+   * Return `true` if this variable was declared with the 'const' modifier.
+   * @return `true` if this variable was declared with the 'const' modifier
    */
-  bool isConst() => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
+  bool get isConst => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
 
   /**
-   * Return {@code true} if this variable was declared with the 'final' modifier. Variables that are
-   * declared with the 'const' modifier will return {@code false} even though they are implicitly
+   * Return `true` if this variable was declared with the 'final' modifier. Variables that are
+   * declared with the 'const' modifier will return `false` even though they are implicitly
    * final.
-   * @return {@code true} if this variable was declared with the 'final' modifier
+   * @return `true` if this variable was declared with the 'final' modifier
    */
-  bool isFinal() => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.FINAL);
+  bool get isFinal => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.FINAL);
 
   /**
    * Set the token representing either the 'final', 'const' or 'var' keyword to the given token.
@@ -4155,12 +4155,12 @@
   }
 }
 /**
- * Instances of the class {@code DefaultFormalParameter} represent a formal parameter with a default
+ * Instances of the class `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})?
+ * defaultFormalParameter ::=[NormalFormalParameter normalFormalParameter] ('=' [Expression defaultValue])?
+ * defaultNamedParameter ::=[NormalFormalParameter normalFormalParameter] (':' [Expression defaultValue])?
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -4177,13 +4177,13 @@
   ParameterKind _kind;
 
   /**
-   * The token separating the parameter from the default value, or {@code null} if there is no
+   * The token separating the parameter from the default value, or `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
+   * The expression computing the default value for the parameter, or `null` if there is no
    * default value.
    */
   Expression _defaultValue;
@@ -4214,7 +4214,7 @@
   Token get beginToken => _parameter.beginToken;
 
   /**
-   * Return the expression computing the default value for the parameter, or {@code null} if there
+   * Return the expression computing the default value for the parameter, or `null` if there
    * is no default value.
    * @return the expression computing the default value for the parameter
    */
@@ -4235,25 +4235,25 @@
   NormalFormalParameter get parameter => _parameter;
 
   /**
-   * Return the token separating the parameter from the default value, or {@code null} if there is
+   * Return the token separating the parameter from the default value, or `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 was declared with the 'const' modifier.
-   * @return {@code true} if this parameter was declared with the 'const' modifier
+   * Return `true` if this parameter was declared with the 'const' modifier.
+   * @return `true` if this parameter was declared with the 'const' modifier
    */
-  bool isConst() => _parameter != null && _parameter.isConst();
+  bool get isConst => _parameter != null && _parameter.isConst;
 
   /**
-   * Return {@code true} if this parameter was declared with the 'final' modifier. Parameters that
-   * are declared with the 'const' modifier will return {@code false} even though they are
+   * Return `true` if this parameter was declared with the 'final' modifier. Parameters that
+   * are declared with the 'const' modifier will return `false` even though they are
    * implicitly final.
-   * @return {@code true} if this parameter was declared with the 'final' modifier
+   * @return `true` if this parameter was declared with the 'final' modifier
    */
-  bool isFinal() => _parameter != null && _parameter.isFinal();
+  bool get isFinal => _parameter != null && _parameter.isFinal;
 
   /**
    * Set the expression computing the default value for the parameter to the given expression.
@@ -4292,16 +4292,16 @@
   }
 }
 /**
- * The abstract class {@code Directive} defines the behavior common to nodes that represent a
+ * The abstract class `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>
+ * directive ::=[ExportDirective exportDirective]| [ImportDirective importDirective]| [LibraryDirective libraryDirective]| [PartDirective partDirective]| [PartOfDirective partOfDirective]</pre>
  * @coverage dart.engine.ast
  */
 abstract class Directive extends AnnotatedNode {
 
   /**
-   * The element associated with this directive, or {@code null} if the AST structure has not been
+   * The element associated with this directive, or `null` if the AST structure has not been
    * resolved or if this directive could not be resolved.
    */
   Element _element;
@@ -4322,7 +4322,7 @@
   Directive({Comment comment, List<Annotation> metadata}) : this.full(comment, metadata);
 
   /**
-   * Return the element associated with this directive, or {@code null} if the AST structure has not
+   * Return the element associated with this directive, or `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
@@ -4345,10 +4345,10 @@
   }
 }
 /**
- * Instances of the class {@code DoStatement} represent a do statement.
+ * Instances of the class `DoStatement` represent a do statement.
  * <pre>
  * doStatement ::=
- * 'do' {@link Statement body} 'while' '(' {@link Expression condition} ')' ';'
+ * 'do' [Statement body] 'while' '(' [Expression condition] ')' ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -4527,7 +4527,7 @@
   }
 }
 /**
- * Instances of the class {@code DoubleLiteral} represent a floating point literal expression.
+ * Instances of the class `DoubleLiteral` represent a floating point literal expression.
  * <pre>
  * doubleLiteral ::=
  * decimalDigit+ ('.' decimalDigit*)? exponent?
@@ -4600,7 +4600,7 @@
   }
 }
 /**
- * Instances of the class {@code EmptyFunctionBody} represent an empty function body, which can only
+ * Instances of the class `EmptyFunctionBody` represent an empty function body, which can only
  * appear in constructors or abstract methods.
  * <pre>
  * emptyFunctionBody ::=
@@ -4650,7 +4650,7 @@
   }
 }
 /**
- * Instances of the class {@code EmptyStatement} represent an empty statement.
+ * Instances of the class `EmptyStatement` represent an empty statement.
  * <pre>
  * emptyStatement ::=
  * ';'
@@ -4708,9 +4708,9 @@
   EphemeralIdentifier({ASTNode parent, int location}) : this.full(parent, location);
 }
 /**
- * Instances of the class {@code ExportDirective} represent an export directive.
+ * Instances of the class `ExportDirective` represent an export directive.
  * <pre>
- * exportDirective ::={@link Annotation metadata} 'export' {@link StringLiteral libraryUri} {@link Combinator combinator}* ';'
+ * exportDirective ::=[Annotation metadata] 'export' [StringLiteral libraryUri] [Combinator combinator]* ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -4752,22 +4752,22 @@
   }
 }
 /**
- * Instances of the class {@code Expression} defines the behavior common to nodes that represent an
+ * Instances of the class `Expression` defines the behavior common to nodes that represent an
  * expression.
  * <pre>
- * expression ::={@link AssignmentExpression assignmentExpression}| {@link ConditionalExpression conditionalExpression} cascadeSection
- * | {@link ThrowExpression throwExpression}</pre>
+ * expression ::=[AssignmentExpression assignmentExpression]| [ConditionalExpression conditionalExpression] cascadeSection
+ * | [ThrowExpression throwExpression]</pre>
  * @coverage dart.engine.ast
  */
 abstract class Expression extends ASTNode {
 
   /**
-   * The static type of this expression, or {@code null} if the AST structure has not been resolved.
+   * The static type of this expression, or `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
+   * The propagated type of this expression, or `null` if type propagation has not been
    * performed on the AST structure.
    */
   Type2 _propagatedType;
@@ -4777,7 +4777,7 @@
    * and the function being invoked is known based on propagated type information, and this
    * expression corresponds to one of the parameters of the function being invoked, then return the
    * parameter element representing the parameter to which the value of this expression will be
-   * bound. Otherwise, return {@code null}.
+   * bound. Otherwise, return `null`.
    * @return the parameter element representing the parameter to which the value of this expression
    * will be bound
    */
@@ -4804,7 +4804,7 @@
   }
 
   /**
-   * Return the propagated type of this expression, or {@code null} if type propagation has not been
+   * Return the propagated type of this expression, or `null` if type propagation has not been
    * performed on the AST structure.
    * @return the propagated type of this expression
    */
@@ -4815,7 +4815,7 @@
    * and the function being invoked is known based on static type information, and this expression
    * corresponds to one of the parameters of the function being invoked, then return the parameter
    * element representing the parameter to which the value of this expression will be bound.
-   * Otherwise, return {@code null}.
+   * Otherwise, return `null`.
    * @return the parameter element representing the parameter to which the value of this expression
    * will be bound
    */
@@ -4842,17 +4842,17 @@
   }
 
   /**
-   * Return the static type of this expression, or {@code null} if the AST structure has not been
+   * Return the static type of this expression, or `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
+   * Return `true` if this expression is syntactically valid for the LHS of an[AssignmentExpression assignment expression].
+   * @return `true` if this expression matches the `assignableExpression` production
    */
-  bool isAssignable() => false;
+  bool get isAssignable => false;
 
   /**
    * Set the propagated type of this expression to the given type.
@@ -4871,11 +4871,11 @@
   }
 }
 /**
- * Instances of the class {@code ExpressionFunctionBody} represent a function body consisting of a
+ * Instances of the class `ExpressionFunctionBody` represent a function body consisting of a
  * single expression.
  * <pre>
  * expressionFunctionBody ::=
- * '=>' {@link Expression expression} ';'
+ * '=>' [Expression expression] ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -4973,9 +4973,9 @@
   }
 }
 /**
- * Instances of the class {@code ExpressionStatement} wrap an expression as a statement.
+ * Instances of the class `ExpressionStatement` wrap an expression as a statement.
  * <pre>
- * expressionStatement ::={@link Expression expression}? ';'
+ * expressionStatement ::=[Expression expression]? ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -4987,7 +4987,7 @@
   Expression _expression;
 
   /**
-   * The semicolon terminating the statement, or {@code null} if the expression is a function
+   * The semicolon terminating the statement, or `null` if the expression is a function
    * expression and isn't followed by a semicolon.
    */
   Token _semicolon;
@@ -5028,7 +5028,7 @@
    * @return the semicolon terminating the statement
    */
   Token get semicolon => _semicolon;
-  bool isSynthetic() => _expression.isSynthetic() && _semicolon.isSynthetic();
+  bool get isSynthetic => _expression.isSynthetic && _semicolon.isSynthetic;
 
   /**
    * Set the expression that comprises the statement to the given expression.
@@ -5050,11 +5050,11 @@
   }
 }
 /**
- * Instances of the class {@code ExtendsClause} represent the "extends" clause in a class
+ * Instances of the class `ExtendsClause` represent the "extends" clause in a class
  * declaration.
  * <pre>
  * extendsClause ::=
- * 'extends' {@link TypeName superclass}</pre>
+ * 'extends' [TypeName superclass]</pre>
  * @coverage dart.engine.ast
  */
 class ExtendsClause extends ASTNode {
@@ -5121,18 +5121,18 @@
   }
 }
 /**
- * Instances of the class {@code FieldDeclaration} represent the declaration of one or more fields
+ * Instances of the class `FieldDeclaration` represent the declaration of one or more fields
  * of the same type.
  * <pre>
  * fieldDeclaration ::=
- * 'static'? {@link VariableDeclarationList fieldList} ';'
+ * 'static'? [VariableDeclarationList fieldList] ';'
  * </pre>
  * @coverage dart.engine.ast
  */
 class FieldDeclaration extends ClassMember {
 
   /**
-   * The token representing the 'static' keyword, or {@code null} if the fields are not static.
+   * The token representing the 'static' keyword, or `null` if the fields are not static.
    */
   Token _keyword;
 
@@ -5180,7 +5180,7 @@
   VariableDeclarationList get fields => _fieldList;
 
   /**
-   * Return the token representing the 'static' keyword, or {@code null} if the fields are not
+   * Return the token representing the 'static' keyword, or `null` if the fields are not
    * static.
    * @return the token representing the 'static' keyword
    */
@@ -5193,10 +5193,10 @@
   Token get semicolon => _semicolon;
 
   /**
-   * Return {@code true} if the fields are static.
-   * @return {@code true} if the fields are declared to be static
+   * Return `true` if the fields are static.
+   * @return `true` if the fields are declared to be static
    */
-  bool isStatic() => _keyword != null;
+  bool get isStatic => _keyword != null;
 
   /**
    * Set the fields being declared to the given list of variables.
@@ -5233,22 +5233,22 @@
   }
 }
 /**
- * Instances of the class {@code FieldFormalParameter} represent a field formal parameter.
+ * Instances of the class `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>
+ * ('final' [TypeName type] | 'const' [TypeName type] | 'var' | [TypeName type])? 'this' '.' [SimpleIdentifier identifier]</pre>
  * @coverage dart.engine.ast
  */
 class FieldFormalParameter extends NormalFormalParameter {
 
   /**
-   * The token representing either the 'final', 'const' or 'var' keyword, or {@code null} if no
+   * The token representing either the 'final', 'const' or 'var' keyword, or `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
+   * The name of the declared type of the parameter, or `null` if the parameter does not have
    * a declared type.
    */
   TypeName _type;
@@ -5321,13 +5321,13 @@
   Token get thisToken => _thisToken;
 
   /**
-   * Return the name of the declared type of the parameter, or {@code null} if the parameter does
+   * Return the name of the declared type of the parameter, or `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) && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
-  bool isFinal() => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.FINAL);
+  bool get isConst => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
+  bool get isFinal => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.FINAL);
 
   /**
    * Set the token representing either the 'final', 'const' or 'var' keyword to the given token.
@@ -5367,10 +5367,10 @@
   }
 }
 /**
- * Instances of the class {@code ForEachStatement} represent a for-each statement.
+ * Instances of the class `ForEachStatement` represent a for-each statement.
  * <pre>
  * forEachStatement ::=
- * 'for' '(' {@link SimpleFormalParameter loopParameter} 'in' {@link Expression iterator} ')' {@link Block body}</pre>
+ * 'for' '(' [SimpleFormalParameter loopParameter] 'in' [Expression iterator] ')' [Block body]</pre>
  * @coverage dart.engine.ast
  */
 class ForEachStatement extends Statement {
@@ -5547,12 +5547,12 @@
   }
 }
 /**
- * Instances of the class {@code ForStatement} represent a for statement.
+ * Instances of the class `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}?
+ * 'for' '(' forLoopParts ')' [Statement statement]forLoopParts ::=
+ * forInitializerStatement ';' [Expression expression]? ';' [Expression expressionList]?
+ * forInitializerStatement ::=[DefaultFormalParameter initializedVariableDeclaration]| [Expression expression]?
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -5569,14 +5569,14 @@
   Token _leftParenthesis;
 
   /**
-   * The declaration of the loop variables, or {@code null} if there are no variables. Note that a
+   * The declaration of the loop variables, or `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
+   * The initialization expression, or `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.
    */
@@ -5676,7 +5676,7 @@
   Token get forKeyword => _forKeyword;
 
   /**
-   * Return the initialization expression, or {@code null} if there is no initialization expression.
+   * Return the initialization expression, or `null` if there is no initialization expression.
    * @return the initialization expression
    */
   Expression get initialization => _initialization;
@@ -5712,8 +5712,8 @@
   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
+   * Return the declaration of the loop variables, or `null` if there are no variables.
+   * @return the declaration of the loop variables, or `null` if there are no variables
    */
   VariableDeclarationList get variables => _variableList;
 
@@ -5797,16 +5797,16 @@
   }
 }
 /**
- * The abstract class {@code FormalParameter} defines the behavior of objects representing a
+ * The abstract class `FormalParameter` defines the behavior of objects representing a
  * parameter to a function.
  * <pre>
- * formalParameter ::={@link NormalFormalParameter normalFormalParameter}| {@link DefaultFormalParameter namedFormalParameter}| {@link DefaultFormalParameter optionalFormalParameter}</pre>
+ * formalParameter ::=[NormalFormalParameter normalFormalParameter]| [DefaultFormalParameter namedFormalParameter]| [DefaultFormalParameter optionalFormalParameter]</pre>
  * @coverage dart.engine.ast
  */
 abstract class FormalParameter extends ASTNode {
 
   /**
-   * Return the element representing this parameter, or {@code null} if this parameter has not been
+   * Return the element representing this parameter, or `null` if this parameter has not been
    * resolved.
    * @return the element representing this parameter
    */
@@ -5831,9 +5831,9 @@
   ParameterKind get kind;
 }
 /**
- * Instances of the class {@code FormalParameterList} represent the formal parameter list of a
+ * Instances of the class `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
@@ -5843,14 +5843,14 @@
  * '(' ')'
  * | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
  * | '(' optionalFormalParameters ')'
- * normalFormalParameters ::={@link NormalFormalParameter normalFormalParameter} (',' {@link NormalFormalParameter normalFormalParameter})
+ * normalFormalParameters ::=[NormalFormalParameter normalFormalParameter] (',' [NormalFormalParameter normalFormalParameter])
  * optionalFormalParameters ::=
  * optionalPositionalFormalParameters
  * | namedFormalParameters
  * optionalPositionalFormalParameters ::=
- * '\[' {@link DefaultFormalParameter positionalFormalParameter} (',' {@link DefaultFormalParameter positionalFormalParameter})* '\]'
+ * '\[' [DefaultFormalParameter positionalFormalParameter] (',' [DefaultFormalParameter positionalFormalParameter])* '\]'
  * namedFormalParameters ::=
- * '{' {@link DefaultFormalParameter namedFormalParameter} (',' {@link DefaultFormalParameter namedFormalParameter})* '}'
+ * '{' [DefaultFormalParameter namedFormalParameter] (',' [DefaultFormalParameter namedFormalParameter])* '}'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -5912,7 +5912,7 @@
 
   /**
    * 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.
+   * will contain `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 {
@@ -5997,44 +5997,44 @@
   }
 }
 /**
- * The abstract class {@code FunctionBody} defines the behavior common to objects representing the
+ * The abstract class `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>
+ * functionBody ::=[BlockFunctionBody blockFunctionBody]| [EmptyFunctionBody emptyFunctionBody]| [ExpressionFunctionBody expressionFunctionBody]</pre>
  * @coverage dart.engine.ast
  */
 abstract class FunctionBody extends ASTNode {
 }
 /**
- * Instances of the class {@code FunctionDeclaration} wrap a {@link FunctionExpression function
- * expression} as a top-level declaration.
+ * Instances of the class `FunctionDeclaration` wrap a [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>
+ * | functionSignature [FunctionBody functionBody]functionSignature ::=[Type returnType]? ('get' | 'set')? [SimpleIdentifier functionName] [FormalParameterList formalParameterList]</pre>
  * @coverage dart.engine.ast
  */
 class FunctionDeclaration extends CompilationUnitMember {
 
   /**
-   * The token representing the 'external' keyword, or {@code null} if this is not an external
+   * The token representing the 'external' keyword, or `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.
+   * The return type of the function, or `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
+   * The token representing the 'get' or 'set' keyword, or `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.
+   * The name of the function, or `null` if the function is not named.
    */
   SimpleIdentifier _name;
 
@@ -6077,7 +6077,7 @@
   Token get endToken => _functionExpression.endToken;
 
   /**
-   * Return the token representing the 'external' keyword, or {@code null} if this is not an
+   * Return the token representing the 'external' keyword, or `null` if this is not an
    * external function.
    * @return the token representing the 'external' keyword
    */
@@ -6090,35 +6090,35 @@
   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, or `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
+   * Return the token representing the 'get' or 'set' keyword, or `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, or `null` if no return type was declared.
    * @return the return type of the function
    */
   TypeName get returnType => _returnType;
 
   /**
-   * Return {@code true} if this function declares a getter.
-   * @return {@code true} if this function declares a getter
+   * Return `true` if this function declares a getter.
+   * @return `true` if this function declares a getter
    */
-  bool isGetter() => _propertyKeyword != null && identical(((_propertyKeyword as KeywordToken)).keyword, Keyword.GET);
+  bool get isGetter => _propertyKeyword != null && identical(((_propertyKeyword as KeywordToken)).keyword, Keyword.GET);
 
   /**
-   * Return {@code true} if this function declares a setter.
-   * @return {@code true} if this function declares a setter
+   * Return `true` if this function declares a setter.
+   * @return `true` if this function declares a setter
    */
-  bool isSetter() => _propertyKeyword != null && identical(((_propertyKeyword as KeywordToken)).keyword, Keyword.SET);
+  bool get isSetter => _propertyKeyword != null && identical(((_propertyKeyword as KeywordToken)).keyword, Keyword.SET);
 
   /**
    * Set the token representing the 'external' keyword to the given token.
@@ -6180,7 +6180,7 @@
   }
 }
 /**
- * Instances of the class {@code FunctionDeclarationStatement} wrap a {@link FunctionDeclarationfunction declaration} as a statement.
+ * Instances of the class `FunctionDeclarationStatement` wrap a [FunctionDeclarationfunction declaration] as a statement.
  * @coverage dart.engine.ast
  */
 class FunctionDeclarationStatement extends Statement {
@@ -6225,9 +6225,9 @@
   }
 }
 /**
- * Instances of the class {@code FunctionExpression} represent a function expression.
+ * Instances of the class `FunctionExpression` represent a function expression.
  * <pre>
- * functionExpression ::={@link FormalParameterList formalParameterList} {@link FunctionBody functionBody}</pre>
+ * functionExpression ::=[FormalParameterList formalParameterList] [FunctionBody functionBody]</pre>
  * @coverage dart.engine.ast
  */
 class FunctionExpression extends Expression {
@@ -6238,12 +6238,12 @@
   FormalParameterList _parameters;
 
   /**
-   * The body of the function, or {@code null} if this is an external function.
+   * The body of the function, or `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
+   * The element associated with the function, or `null` if the AST structure has not been
    * resolved.
    */
   ExecutableElement _element;
@@ -6275,13 +6275,13 @@
   }
 
   /**
-   * Return the body of the function, or {@code null} if this is an external function.
+   * Return the body of the function, or `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
+   * Return the element associated with this function, or `null` if the AST structure has not
    * been resolved.
    * @return the element associated with this function
    */
@@ -6330,12 +6330,12 @@
   }
 }
 /**
- * Instances of the class {@code FunctionExpressionInvocation} represent the invocation of a
+ * Instances of the class `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.
+ * functions are represented by [MethodInvocation method invocation] nodes. Invocations of
+ * getters and setters are represented by either [PrefixedIdentifier prefixed identifier] or[PropertyAccess property access] nodes.
  * <pre>
- * functionExpressionInvoction ::={@link Expression function} {@link ArgumentList argumentList}</pre>
+ * functionExpressionInvoction ::=[Expression function] [ArgumentList argumentList]</pre>
  * @coverage dart.engine.ast
  */
 class FunctionExpressionInvocation extends Expression {
@@ -6351,12 +6351,12 @@
   ArgumentList _argumentList;
 
   /**
-   * The element associated with the function being invoked based on static type information, or{@code null} if the AST structure has not been resolved or the function could not be resolved.
+   * The element associated with the function being invoked based on static type information, or`null` if the AST structure has not been resolved or the function could not be resolved.
    */
   ExecutableElement _staticElement;
 
   /**
-   * The element associated with the function being invoked based on propagated type information, or{@code null} if the AST structure has not been resolved or the function could not be resolved.
+   * The element associated with the function being invoked based on propagated type information, or`null` if the AST structure has not been resolved or the function could not be resolved.
    */
   ExecutableElement _propagatedElement;
 
@@ -6387,7 +6387,7 @@
 
   /**
    * Return the element associated with the function being invoked based on propagated type
-   * information, or {@code null} if the AST structure has not been resolved or the function could
+   * information, or `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
@@ -6403,7 +6403,7 @@
 
   /**
    * Return the element associated with the function being invoked based on static type information,
-   * or {@code null} if the AST structure has not been resolved or the function could not be
+   * or `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
@@ -6449,17 +6449,17 @@
   }
 }
 /**
- * Instances of the class {@code FunctionTypeAlias} represent a function type alias.
+ * Instances of the class `FunctionTypeAlias` represent a function type alias.
  * <pre>
  * functionTypeAlias ::=
- * functionPrefix {@link TypeParameterList typeParameterList}? {@link FormalParameterList formalParameterList} ';'
- * functionPrefix ::={@link TypeName returnType}? {@link SimpleIdentifier name}</pre>
+ * functionPrefix [TypeParameterList typeParameterList]? [FormalParameterList formalParameterList] ';'
+ * functionPrefix ::=[TypeName returnType]? [SimpleIdentifier name]</pre>
  * @coverage dart.engine.ast
  */
 class FunctionTypeAlias extends TypeAlias {
 
   /**
-   * The name of the return type of the function type being defined, or {@code null} if no return
+   * The name of the return type of the function type being defined, or `null` if no return
    * type was given.
    */
   TypeName _returnType;
@@ -6470,7 +6470,7 @@
   SimpleIdentifier _name;
 
   /**
-   * The type parameters for the function type, or {@code null} if the function type does not have
+   * The type parameters for the function type, or `null` if the function type does not have
    * any type parameters.
    */
   TypeParameterList _typeParameters;
@@ -6526,14 +6526,14 @@
   FormalParameterList get parameters => _parameters;
 
   /**
-   * Return the name of the return type of the function type being defined, or {@code null} if no
+   * Return the name of the return type of the function type being defined, or `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
+   * Return the type parameters for the function type, or `null` if the function type does not
    * have any type parameters.
    * @return the type parameters for the function type
    */
@@ -6579,16 +6579,16 @@
   }
 }
 /**
- * Instances of the class {@code FunctionTypedFormalParameter} represent a function-typed formal
+ * Instances of the class `FunctionTypedFormalParameter` represent a function-typed formal
  * parameter.
  * <pre>
- * functionSignature ::={@link TypeName returnType}? {@link SimpleIdentifier identifier} {@link FormalParameterList formalParameterList}</pre>
+ * functionSignature ::=[TypeName returnType]? [SimpleIdentifier identifier] [FormalParameterList formalParameterList]</pre>
  * @coverage dart.engine.ast
  */
 class FunctionTypedFormalParameter extends NormalFormalParameter {
 
   /**
-   * The return type of the function, or {@code null} if the function does not have a return type.
+   * The return type of the function, or `null` if the function does not have a return type.
    */
   TypeName _returnType;
 
@@ -6601,7 +6601,7 @@
    * 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
+   * @param returnType the return type of the function, or `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
@@ -6615,7 +6615,7 @@
    * 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
+   * @param returnType the return type of the function, or `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
@@ -6637,13 +6637,13 @@
   FormalParameterList get parameters => _parameters;
 
   /**
-   * Return the return type of the function, or {@code null} if the function does not have a return
+   * Return the return type of the function, or `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;
+  bool get isConst => false;
+  bool get isFinal => false;
 
   /**
    * Set the parameters of the function-typed parameter to the given parameters.
@@ -6668,11 +6668,11 @@
   }
 }
 /**
- * Instances of the class {@code HideCombinator} represent a combinator that restricts the names
+ * Instances of the class `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})
+ * 'hide' [SimpleIdentifier identifier] (',' [SimpleIdentifier identifier])
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -6712,24 +6712,24 @@
   }
 }
 /**
- * The abstract class {@code Identifier} defines the behavior common to nodes that represent an
+ * The abstract class `Identifier` defines the behavior common to nodes that represent an
  * identifier.
  * <pre>
- * identifier ::={@link SimpleIdentifier simpleIdentifier}| {@link PrefixedIdentifier prefixedIdentifier}</pre>
+ * identifier ::=[SimpleIdentifier simpleIdentifier]| [PrefixedIdentifier prefixedIdentifier]</pre>
  * @coverage dart.engine.ast
  */
 abstract class Identifier extends Expression {
 
   /**
-   * Return {@code true} if the given name is visible only within the library in which it is
+   * Return `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
+   * @return `true` if the given name is private
    */
   static bool isPrivateName(String name) => name.startsWith("_");
 
   /**
-   * Return the element associated with this identifier based on propagated type information, or{@code null} if the AST structure has not been resolved or if this identifier could not be
+   * Return the element associated with this identifier based on propagated type information, or`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
@@ -6743,19 +6743,19 @@
   String get name;
 
   /**
-   * Return the element associated with this identifier based on static type information, or{@code null} if the AST structure has not been resolved or if this identifier could not be
+   * Return the element associated with this identifier based on static type information, or`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 the operator
    */
   Element get staticElement;
-  bool isAssignable() => true;
+  bool get isAssignable => true;
 }
 /**
- * Instances of the class {@code IfStatement} represent an if statement.
+ * Instances of the class `IfStatement` represent an if statement.
  * <pre>
  * ifStatement ::=
- * 'if' '(' {@link Expression expression} ')' {@link Statement thenStatement} ('else' {@link Statement elseStatement})?
+ * 'if' '(' [Expression expression] ')' [Statement thenStatement] ('else' [Statement elseStatement])?
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -6782,7 +6782,7 @@
   Token _rightParenthesis;
 
   /**
-   * The statement that is executed if the condition evaluates to {@code true}.
+   * The statement that is executed if the condition evaluates to `true`.
    */
   Statement _thenStatement;
 
@@ -6792,7 +6792,7 @@
   Token _elseKeyword;
 
   /**
-   * The statement that is executed if the condition evaluates to {@code false}, or {@code null} if
+   * The statement that is executed if the condition evaluates to `false`, or `null` if
    * there is no else statement.
    */
   Statement _elseStatement;
@@ -6803,9 +6803,9 @@
    * @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 thenStatement the statement that is executed if the condition evaluates to `true`
    * @param elseKeyword the token representing the 'else' keyword
-   * @param elseStatement the statement that is executed if the condition evaluates to {@code false}
+   * @param elseStatement the statement that is executed if the condition evaluates to `false`
    */
   IfStatement.full(Token ifKeyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Statement thenStatement, Token elseKeyword, Statement elseStatement) {
     this._ifKeyword = ifKeyword;
@@ -6823,9 +6823,9 @@
    * @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 thenStatement the statement that is executed if the condition evaluates to `true`
    * @param elseKeyword the token representing the 'else' keyword
-   * @param elseStatement the statement that is executed if the condition evaluates to {@code false}
+   * @param elseStatement the statement that is executed if the condition evaluates to `false`
    */
   IfStatement({Token ifKeyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Statement thenStatement, Token elseKeyword, Statement elseStatement}) : this.full(ifKeyword, leftParenthesis, condition, rightParenthesis, thenStatement, elseKeyword, elseStatement);
   accept(ASTVisitor visitor) => visitor.visitIfStatement(this);
@@ -6844,8 +6844,8 @@
   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}
+   * Return the statement that is executed if the condition evaluates to `false`, or`null` if there is no else statement.
+   * @return the statement that is executed if the condition evaluates to `false`
    */
   Statement get elseStatement => _elseStatement;
   Token get endToken {
@@ -6874,8 +6874,8 @@
   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}
+   * Return the statement that is executed if the condition evaluates to `true`.
+   * @return the statement that is executed if the condition evaluates to `true`
    */
   Statement get thenStatement => _thenStatement;
 
@@ -6897,9 +6897,9 @@
   }
 
   /**
-   * Set the statement that is executed if the condition evaluates to {@code false} to the given
+   * Set the statement that is executed if the condition evaluates to `false` to the given
    * statement.
-   * @param statement the statement that is executed if the condition evaluates to {@code false}
+   * @param statement the statement that is executed if the condition evaluates to `false`
    */
   void set elseStatement(Statement statement) {
     _elseStatement = becomeParentOf(statement);
@@ -6930,9 +6930,9 @@
   }
 
   /**
-   * Set the statement that is executed if the condition evaluates to {@code true} to the given
+   * Set the statement that is executed if the condition evaluates to `true` to the given
    * statement.
-   * @param statement the statement that is executed if the condition evaluates to {@code true}
+   * @param statement the statement that is executed if the condition evaluates to `true`
    */
   void set thenStatement(Statement statement) {
     _thenStatement = becomeParentOf(statement);
@@ -6944,11 +6944,11 @@
   }
 }
 /**
- * Instances of the class {@code ImplementsClause} represent the "implements" clause in an class
+ * Instances of the class `ImplementsClause` represent the "implements" clause in an class
  * declaration.
  * <pre>
  * implementsClause ::=
- * 'implements' {@link TypeName superclass} (',' {@link TypeName superclass})
+ * 'implements' [TypeName superclass] (',' [TypeName superclass])
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -7009,21 +7009,21 @@
   }
 }
 /**
- * Instances of the class {@code ImportDirective} represent an import directive.
+ * Instances of the class `ImportDirective` represent an import directive.
  * <pre>
- * importDirective ::={@link Annotation metadata} 'import' {@link StringLiteral libraryUri} ('as' identifier)? {@link Combinator combinator}* ';'
+ * importDirective ::=[Annotation metadata] 'import' [StringLiteral libraryUri] ('as' identifier)? [Combinator combinator]* ';'
  * </pre>
  * @coverage dart.engine.ast
  */
 class ImportDirective extends NamespaceDirective {
 
   /**
-   * The token representing the 'as' token, or {@code null} if the imported names are not prefixed.
+   * The token representing the 'as' token, or `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
+   * The prefix to be used with the imported names, or `null` if the imported names are not
    * prefixed.
    */
   SimpleIdentifier _prefix;
@@ -7059,14 +7059,14 @@
   accept(ASTVisitor visitor) => visitor.visitImportDirective(this);
 
   /**
-   * Return the token representing the 'as' token, or {@code null} if the imported names are not
+   * Return the token representing the 'as' token, or `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
+   * Return the prefix to be used with the imported names, or `null` if the imported names are
    * not prefixed.
    * @return the prefix to be used with the imported names
    */
@@ -7101,22 +7101,22 @@
   }
 }
 /**
- * Instances of the class {@code IndexExpression} represent an index expression.
+ * Instances of the class `IndexExpression` represent an index expression.
  * <pre>
- * indexExpression ::={@link Expression target} '\[' {@link Expression index} '\]'
+ * indexExpression ::=[Expression target] '\[' [Expression index] '\]'
  * </pre>
  * @coverage dart.engine.ast
  */
 class IndexExpression extends Expression {
 
   /**
-   * The expression used to compute the object being indexed, or {@code null} if this index
+   * The expression used to compute the object being indexed, or `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
+   * The period ("..") before a cascaded index expression, or `null` if this index expression
    * is not part of a cascade expression.
    */
   Token _period;
@@ -7137,13 +7137,13 @@
   Token _rightBracket;
 
   /**
-   * The element associated with the operator based on the static type of the target, or{@code null} if the AST structure has not been resolved or if the operator could not be
+   * The element associated with the operator based on the static type of the target, or`null` if the AST structure has not been resolved or if the operator could not be
    * resolved.
    */
   MethodElement _staticElement;
 
   /**
-   * The element associated with the operator based on the propagated type of the target, or{@code null} if the AST structure has not been resolved or if the operator could not be
+   * The element associated with the operator based on the propagated type of the target, or`null` if the AST structure has not been resolved or if the operator could not be
    * resolved.
    */
   MethodElement _propagatedElement;
@@ -7202,7 +7202,7 @@
   accept(ASTVisitor visitor) => visitor.visitIndexExpression(this);
 
   /**
-   * Return the expression used to compute the object being indexed, or {@code null} if this index
+   * Return the expression used to compute the object being indexed, or `null` if this index
    * expression is part of a cascade expression.
    * @return the expression used to compute the object being indexed
    * @see #getRealTarget()
@@ -7216,7 +7216,7 @@
   }
 
   /**
-   * Return the element associated with the operator based on the propagated type of the target, or{@code null} if the AST structure has not been resolved or if the operator could not be
+   * Return the element associated with the operator based on the propagated type of the target, or`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
    * target.
    * @return the element associated with this operator
@@ -7237,7 +7237,7 @@
   Token get leftBracket => _leftBracket;
 
   /**
-   * Return the period ("..") before a cascaded index expression, or {@code null} if this index
+   * Return the period ("..") before a cascaded index expression, or `null` if this index
    * expression is not part of a cascade expression.
    * @return the period ("..") before a cascaded index expression
    */
@@ -7245,14 +7245,14 @@
 
   /**
    * 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
+   * part of a cascade expression, then this is the same as [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()) {
+    if (isCascaded) {
       ASTNode ancestor = parent;
       while (ancestor is! CascadeExpression) {
         if (ancestor == null) {
@@ -7272,7 +7272,7 @@
   Token get rightBracket => _rightBracket;
 
   /**
-   * Return the element associated with the operator based on the static type of the target, or{@code null} if the AST structure has not been resolved or if the operator could not be
+   * Return the element associated with the operator based on the static type of the target, or`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
    * target.
    * @return the element associated with the operator
@@ -7280,11 +7280,11 @@
   MethodElement get staticElement => _staticElement;
 
   /**
-   * 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
+   * Return `true` if this expression is computing a right-hand value.
+   *
+   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor are
+   * they mutually exclusive. In other words, it is possible for both methods to return `true`when invoked on the same node.
+   * @return `true` if this expression is in a context where the operator '\[\]' will be invoked
    */
   bool inGetterContext() {
     ASTNode parent = this.parent;
@@ -7298,17 +7298,17 @@
   }
 
   /**
-   * 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
+   * Return `true` if this expression is computing a left-hand value.
+   *
+   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor are
+   * they mutually exclusive. In other words, it is possible for both methods to return `true`when invoked on the same node.
+   * @return `true` if this expression is in a context where the operator '\[\]=' will be
    * invoked
    */
   bool inSetterContext() {
     ASTNode parent = this.parent;
     if (parent is PrefixExpression) {
-      return ((parent as PrefixExpression)).operator.type.isIncrementOperator();
+      return ((parent as PrefixExpression)).operator.type.isIncrementOperator;
     } else if (parent is PostfixExpression) {
       return true;
     } else if (parent is AssignmentExpression) {
@@ -7316,14 +7316,14 @@
     }
     return false;
   }
-  bool isAssignable() => true;
+  bool get 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
+   * Return `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[CascadeExpression].
+   * @return `true` if this expression is cascaded
    */
-  bool isCascaded() => _period != null;
+  bool get isCascaded => _period != null;
 
   /**
    * Set the expression used to compute the object being indexed to the given expression.
@@ -7390,9 +7390,9 @@
   /**
    * If the AST structure has been resolved, and the function being invoked is known based on
    * propagated type information, then return the parameter element representing the parameter to
-   * which the value of the index expression will be bound. Otherwise, return {@code null}.
-   * <p>
-   * This method is only intended to be used by {@link Expression#getParameterElement()}.
+   * which the value of the index expression will be bound. Otherwise, return `null`.
+   *
+   * This method is only intended to be used by [Expression#getParameterElement].
    * @return the parameter element representing the parameter to which the value of the index
    * expression will be bound
    */
@@ -7410,9 +7410,9 @@
   /**
    * If the AST structure has been resolved, and the function being invoked is known based on static
    * type information, then return the parameter element representing the parameter to which the
-   * value of the index expression will be bound. Otherwise, return {@code null}.
-   * <p>
-   * This method is only intended to be used by {@link Expression#getStaticParameterElement()}.
+   * value of the index expression will be bound. Otherwise, return `null`.
+   *
+   * This method is only intended to be used by [Expression#getStaticParameterElement].
    * @return the parameter element representing the parameter to which the value of the index
    * expression will be bound
    */
@@ -7428,11 +7428,11 @@
   }
 }
 /**
- * Instances of the class {@code InstanceCreationExpression} represent an instance creation
+ * Instances of the class `InstanceCreationExpression` represent an instance creation
  * expression.
  * <pre>
  * newExpression ::=
- * ('new' | 'const') {@link TypeName type} ('.' {@link SimpleIdentifier identifier})? {@link ArgumentList argumentList}</pre>
+ * ('new' | 'const') [TypeName type] ('.' [SimpleIdentifier identifier])? [ArgumentList argumentList]</pre>
  * @coverage dart.engine.ast
  */
 class InstanceCreationExpression extends Expression {
@@ -7453,12 +7453,12 @@
   ArgumentList _argumentList;
 
   /**
-   * The element associated with the constructor based on static type information, or {@code null}if the AST structure has not been resolved or if the constructor could not be resolved.
+   * The element associated with the constructor based on static type information, or `null`if the AST structure has not been resolved or if the constructor could not be resolved.
    */
   ConstructorElement _staticElement;
 
   /**
-   * The element associated with the constructor based on propagated type information, or{@code null} if the AST structure has not been resolved or if the constructor could not be
+   * The element associated with the constructor based on propagated type information, or`null` if the AST structure has not been resolved or if the constructor could not be
    * resolved.
    */
   ConstructorElement _propagatedElement;
@@ -7498,7 +7498,7 @@
   ConstructorName get constructorName => _constructorName;
 
   /**
-   * Return the element associated with the constructor based on propagated type information, or{@code null} if the AST structure has not been resolved or if the constructor could not be
+   * Return the element associated with the constructor based on propagated type information, or`null` if the AST structure has not been resolved or if the constructor could not be
    * resolved.
    * @return the element associated with the constructor
    */
@@ -7512,17 +7512,17 @@
   Token get keyword => _keyword;
 
   /**
-   * Return the element associated with the constructor based on static type information, or{@code null} if the AST structure has not been resolved or if the constructor could not be
+   * Return the element associated with the constructor based on static type information, or`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 staticElement => _staticElement;
 
   /**
-   * Return {@code true} if this creation expression is used to invoke a constant constructor.
-   * @return {@code true} if this creation expression is used to invoke a constant constructor
+   * Return `true` if this creation expression is used to invoke a constant constructor.
+   * @return `true` if this creation expression is used to invoke a constant constructor
    */
-  bool isConst() => _keyword is KeywordToken && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
+  bool get isConst => _keyword is KeywordToken && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
 
   /**
    * Set the list of arguments to the constructor to the given list.
@@ -7571,7 +7571,7 @@
   }
 }
 /**
- * Instances of the class {@code IntegerLiteral} represent an integer literal expression.
+ * Instances of the class `IntegerLiteral` represent an integer literal expression.
  * <pre>
  * integerLiteral ::=
  * decimalIntegerLiteral
@@ -7647,19 +7647,19 @@
   }
 }
 /**
- * The abstract class {@code InterpolationElement} defines the behavior common to elements within a{@link StringInterpolation string interpolation}.
+ * The abstract class `InterpolationElement` defines the behavior common to elements within a[StringInterpolation string interpolation].
  * <pre>
- * interpolationElement ::={@link InterpolationExpression interpolationExpression}| {@link InterpolationString interpolationString}</pre>
+ * interpolationElement ::=[InterpolationExpression interpolationExpression]| [InterpolationString interpolationString]</pre>
  * @coverage dart.engine.ast
  */
 abstract class InterpolationElement extends ASTNode {
 }
 /**
- * Instances of the class {@code InterpolationExpression} represent an expression embedded in a
+ * Instances of the class `InterpolationExpression` represent an expression embedded in a
  * string interpolation.
  * <pre>
  * interpolationExpression ::=
- * '$' {@link SimpleIdentifier identifier}| '$' '{' {@link Expression expression} '}'
+ * '$' [SimpleIdentifier identifier]| '$' '{' [Expression expression] '}'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -7677,7 +7677,7 @@
   Expression _expression;
 
   /**
-   * The right curly bracket, or {@code null} if the expression is an identifier without brackets.
+   * The right curly bracket, or `null` if the expression is an identifier without brackets.
    */
   Token _rightBracket;
 
@@ -7756,7 +7756,7 @@
   }
 }
 /**
- * Instances of the class {@code InterpolationString} represent a non-empty substring of an
+ * Instances of the class `InterpolationString` represent a non-empty substring of an
  * interpolated string.
  * <pre>
  * interpolationString ::=
@@ -7827,9 +7827,9 @@
   }
 }
 /**
- * Instances of the class {@code IsExpression} represent an is expression.
+ * Instances of the class `IsExpression` represent an is expression.
  * <pre>
- * isExpression ::={@link Expression expression} 'is' '!'? {@link TypeName type}</pre>
+ * isExpression ::=[Expression expression] 'is' '!'? [TypeName type]</pre>
  * @coverage dart.engine.ast
  */
 class IsExpression extends Expression {
@@ -7845,7 +7845,7 @@
   Token _isOperator;
 
   /**
-   * The not operator, or {@code null} if the sense of the test is not negated.
+   * The not operator, or `null` if the sense of the test is not negated.
    */
   Token _notOperator;
 
@@ -7858,7 +7858,7 @@
    * 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 notOperator the not operator, or `null` if the sense of the test is not negated
    * @param type the name of the type being tested for
    */
   IsExpression.full(Expression expression, Token isOperator, Token notOperator, TypeName type) {
@@ -7872,7 +7872,7 @@
    * 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 notOperator the not operator, or `null` if the sense of the test is not negated
    * @param type the name of the type being tested for
    */
   IsExpression({Expression expression, Token isOperator, Token notOperator, TypeName type}) : this.full(expression, isOperator, notOperator, type);
@@ -7942,9 +7942,9 @@
   }
 }
 /**
- * Instances of the class {@code Label} represent a label.
+ * Instances of the class `Label` represent a label.
  * <pre>
- * label ::={@link SimpleIdentifier label} ':'
+ * label ::=[SimpleIdentifier label] ':'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -8012,10 +8012,10 @@
   }
 }
 /**
- * Instances of the class {@code LabeledStatement} represent a statement that has a label associated
+ * Instances of the class `LabeledStatement` represent a statement that has a label associated
  * with them.
  * <pre>
- * labeledStatement ::={@link Label label}+ {@link Statement statement}</pre>
+ * labeledStatement ::=[Label label]+ [Statement statement]</pre>
  * @coverage dart.engine.ast
  */
 class LabeledStatement extends Statement {
@@ -8081,9 +8081,9 @@
   }
 }
 /**
- * Instances of the class {@code LibraryDirective} represent a library directive.
+ * Instances of the class `LibraryDirective` represent a library directive.
  * <pre>
- * libraryDirective ::={@link Annotation metadata} 'library' {@link Identifier name} ';'
+ * libraryDirective ::=[Annotation metadata] 'library' [Identifier name] ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -8179,9 +8179,9 @@
   Token get firstTokenAfterCommentAndMetadata => _libraryToken;
 }
 /**
- * Instances of the class {@code LibraryIdentifier} represent the identifier for a library.
+ * Instances of the class `LibraryIdentifier` represent the identifier for a library.
  * <pre>
- * libraryIdentifier ::={@link SimpleIdentifier component} ('.' {@link SimpleIdentifier component})
+ * libraryIdentifier ::=[SimpleIdentifier component] ('.' [SimpleIdentifier component])
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -8235,10 +8235,10 @@
   }
 }
 /**
- * Instances of the class {@code ListLiteral} represent a list literal.
+ * Instances of the class `ListLiteral` represent a list literal.
  * <pre>
  * listLiteral ::=
- * 'const'? ('<' {@link TypeName type} '>')? '\[' ({@link Expression expressionList} ','?)? '\]'
+ * 'const'? ('<' [TypeName type] '>')? '\[' ([Expression expressionList] ','?)? '\]'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -8262,7 +8262,7 @@
   /**
    * 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
+   * @param typeArguments the type argument associated with this literal, or `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
@@ -8278,7 +8278,7 @@
   /**
    * 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
+   * @param typeArguments the type argument associated with this literal, or `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
@@ -8338,19 +8338,19 @@
   }
 }
 /**
- * The abstract class {@code Literal} defines the behavior common to nodes that represent a literal
+ * The abstract class `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>
+ * literal ::=[BooleanLiteral booleanLiteral]| [DoubleLiteral doubleLiteral]| [IntegerLiteral integerLiteral]| [ListLiteral listLiteral]| [MapLiteral mapLiteral]| [NullLiteral nullLiteral]| [StringLiteral stringLiteral]</pre>
  * @coverage dart.engine.ast
  */
 abstract class Literal extends Expression {
 }
 /**
- * Instances of the class {@code MapLiteral} represent a literal map.
+ * Instances of the class `MapLiteral` represent a literal map.
  * <pre>
  * mapLiteral ::=
- * 'const'? ('<' {@link TypeName type} (',' {@link TypeName type})* '>')? '{' ({@link MapLiteralEntry entry} (',' {@link MapLiteralEntry entry})* ','?)? '}'
+ * 'const'? ('<' [TypeName type] (',' [TypeName type])* '>')? '{' ([MapLiteralEntry entry] (',' [MapLiteralEntry entry])* ','?)? '}'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -8374,7 +8374,7 @@
   /**
    * 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
+   * @param typeArguments the type argument associated with this literal, or `null` if no type
    * arguments were declared
    * @param leftBracket the left curly bracket
    * @param entries the entries in the map
@@ -8390,7 +8390,7 @@
   /**
    * 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
+   * @param typeArguments the type argument associated with this literal, or `null` if no type
    * arguments were declared
    * @param leftBracket the left curly bracket
    * @param entries the entries in the map
@@ -8450,10 +8450,10 @@
   }
 }
 /**
- * Instances of the class {@code MapLiteralEntry} represent a single key/value pair in a map
+ * Instances of the class `MapLiteralEntry` represent a single key/value pair in a map
  * literal.
  * <pre>
- * mapLiteralEntry ::={@link Expression key} ':' {@link Expression value}</pre>
+ * mapLiteralEntry ::=[Expression key] ':' [Expression value]</pre>
  * @coverage dart.engine.ast
  */
 class MapLiteralEntry extends ASTNode {
@@ -8545,39 +8545,39 @@
   }
 }
 /**
- * Instances of the class {@code MethodDeclaration} represent a method declaration.
+ * Instances of the class `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}| 'operator' {@link SimpleIdentifier operator}</pre>
+ * methodSignature [FunctionBody body]methodSignature ::=
+ * 'external'? ('abstract' | 'static')? [Type returnType]? ('get' | 'set')? methodName[FormalParameterList formalParameterList]methodName ::=[SimpleIdentifier name]| 'operator' [SimpleIdentifier operator]</pre>
  * @coverage dart.engine.ast
  */
 class MethodDeclaration extends ClassMember {
 
   /**
-   * The token for the 'external' keyword, or {@code null} if the constructor is not external.
+   * The token for the 'external' keyword, or `null` if the constructor is not external.
    */
   Token _externalKeyword;
 
   /**
-   * The token representing the 'abstract' or 'static' keyword, or {@code null} if neither modifier
+   * The token representing the 'abstract' or 'static' keyword, or `null` if neither modifier
    * was specified.
    */
   Token _modifierKeyword;
 
   /**
-   * The return type of the method, or {@code null} if no return type was declared.
+   * The return type of the method, or `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
+   * The token representing the 'get' or 'set' keyword, or `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
+   * The token representing the 'operator' keyword, or `null` if this method does not declare
    * an operator.
    */
   Token _operatorKeyword;
@@ -8588,7 +8588,7 @@
   SimpleIdentifier _name;
 
   /**
-   * The parameters associated with the method, or {@code null} if this method declares a getter.
+   * The parameters associated with the method, or `null` if this method declares a getter.
    */
   FormalParameterList _parameters;
 
@@ -8607,7 +8607,7 @@
    * @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
+   * @param parameters the parameters associated with the method, or `null` if this method
    * declares a getter
    * @param body the body of the method
    */
@@ -8632,7 +8632,7 @@
    * @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
+   * @param parameters the parameters associated with the method, or `null` if this method
    * declares a getter
    * @param body the body of the method
    */
@@ -8646,9 +8646,9 @@
   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
+   * Return the element associated with this method, or `null` if the AST structure has not
+   * been resolved. The element can either be a [MethodElement], if this represents the
+   * declaration of a normal method, or a [PropertyAccessorElement] if this represents the
    * declaration of either a getter or a setter.
    * @return the element associated with this method
    */
@@ -8656,14 +8656,14 @@
   Token get endToken => _body.endToken;
 
   /**
-   * Return the token for the 'external' keyword, or {@code null} if the constructor is not
+   * Return the token for the 'external' keyword, or `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
+   * Return the token representing the 'abstract' or 'static' keyword, or `null` if neither
    * modifier was specified.
    * @return the token representing the 'abstract' or 'static' keyword
    */
@@ -8676,61 +8676,61 @@
   SimpleIdentifier get name => _name;
 
   /**
-   * Return the token representing the 'operator' keyword, or {@code null} if this method does not
+   * Return the token representing the 'operator' keyword, or `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
+   * Return the parameters associated with the method, or `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
+   * Return the token representing the 'get' or 'set' keyword, or `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, or `null` if no return type was declared.
    * @return the return type of the method
    */
   TypeName get returnType => _returnType;
 
   /**
-   * Return {@code true} if this method is declared to be an abstract method.
-   * @return {@code true} if this method is declared to be an abstract method
+   * Return `true` if this method is declared to be an abstract method.
+   * @return `true` if this method is declared to be an abstract method
    */
-  bool isAbstract() => _externalKeyword == null && (_body is EmptyFunctionBody);
+  bool get isAbstract => _externalKeyword == null && (_body is EmptyFunctionBody);
 
   /**
-   * Return {@code true} if this method declares a getter.
-   * @return {@code true} if this method declares a getter
+   * Return `true` if this method declares a getter.
+   * @return `true` if this method declares a getter
    */
-  bool isGetter() => _propertyKeyword != null && identical(((_propertyKeyword as KeywordToken)).keyword, Keyword.GET);
+  bool get isGetter => _propertyKeyword != null && identical(((_propertyKeyword as KeywordToken)).keyword, Keyword.GET);
 
   /**
-   * Return {@code true} if this method declares an operator.
-   * @return {@code true} if this method declares an operator
+   * Return `true` if this method declares an operator.
+   * @return `true` if this method declares an operator
    */
-  bool isOperator() => _operatorKeyword != null;
+  bool get isOperator => _operatorKeyword != null;
 
   /**
-   * Return {@code true} if this method declares a setter.
-   * @return {@code true} if this method declares a setter
+   * Return `true` if this method declares a setter.
+   * @return `true` if this method declares a setter
    */
-  bool isSetter() => _propertyKeyword != null && identical(((_propertyKeyword as KeywordToken)).keyword, Keyword.SET);
+  bool get isSetter => _propertyKeyword != null && identical(((_propertyKeyword as KeywordToken)).keyword, Keyword.SET);
 
   /**
-   * Return {@code true} if this method is declared to be a static method.
-   * @return {@code true} if this method is declared to be a static method
+   * Return `true` if this method is declared to be a static method.
+   * @return `true` if this method is declared to be a static method
    */
-  bool isStatic() => _modifierKeyword != null && identical(((_modifierKeyword as KeywordToken)).keyword, Keyword.STATIC);
+  bool get isStatic => _modifierKeyword != null && identical(((_modifierKeyword as KeywordToken)).keyword, Keyword.STATIC);
 
   /**
    * Set the body of the method to the given function body.
@@ -8816,24 +8816,24 @@
   }
 }
 /**
- * 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.
+ * Instances of the class `MethodInvocation` represent the invocation of either a function or
+ * a method. Invocations of functions resulting from evaluating an expression are represented by[FunctionExpressionInvocation function expression invocation] nodes. Invocations of getters
+ * and setters are represented by either [PrefixedIdentifier prefixed identifier] or[PropertyAccess property access] nodes.
  * <pre>
  * methodInvoction ::=
- * ({@link Expression target} '.')? {@link SimpleIdentifier methodName} {@link ArgumentList argumentList}</pre>
+ * ([Expression target] '.')? [SimpleIdentifier methodName] [ArgumentList argumentList]</pre>
  * @coverage dart.engine.ast
  */
 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}).
+   * The expression producing the object on which the method is defined, or `null` if there is
+   * no target (that is, the target is implicitly `this`).
    */
   Expression _target;
 
   /**
-   * The period that separates the target from the method name, or {@code null} if there is no
+   * The period that separates the target from the method name, or `null` if there is no
    * target.
    */
   Token _period;
@@ -8894,7 +8894,7 @@
   SimpleIdentifier get methodName => _methodName;
 
   /**
-   * Return the period that separates the target from the method name, or {@code null} if there is
+   * Return the period that separates the target from the method name, or `null` if there is
    * no target.
    * @return the period that separates the target from the method name
    */
@@ -8902,14 +8902,14 @@
 
   /**
    * 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
+   * part of a cascade expression, then this is the same as [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()) {
+    if (isCascaded) {
       ASTNode ancestor = parent;
       while (ancestor is! CascadeExpression) {
         if (ancestor == null) {
@@ -8923,8 +8923,8 @@
   }
 
   /**
-   * 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
+   * Return the expression producing the object on which the method is defined, or `null` if
+   * there is no target (that is, the target is implicitly `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()
@@ -8932,11 +8932,11 @@
   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
+   * Return `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[CascadeExpression].
+   * @return `true` if this expression is cascaded
    */
-  bool isCascaded() => _period != null && identical(_period.type, TokenType.PERIOD_PERIOD);
+  bool get isCascaded => _period != null && identical(_period.type, TokenType.PERIOD_PERIOD);
 
   /**
    * Set the list of arguments to the method to the given list.
@@ -8976,10 +8976,10 @@
   }
 }
 /**
- * Instances of the class {@code NamedExpression} represent an expression that has a name associated
+ * Instances of the class `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>
+ * namedExpression ::=[Label name] [Expression expression]</pre>
  * @coverage dart.engine.ast
  */
 class NamedExpression extends Expression {
@@ -9014,7 +9014,7 @@
   Token get beginToken => _name.beginToken;
 
   /**
-   * Return the element representing the parameter being named by this expression, or {@code null}if the AST structure has not been resolved or if there is no parameter with the same name as
+   * Return the element representing the parameter being named by this expression, or `null`if the AST structure has not been resolved or if there is no parameter with the same name as
    * this expression.
    * @return the element representing the parameter being named by this expression
    */
@@ -9060,10 +9060,10 @@
   }
 }
 /**
- * The abstract class {@code NamespaceDirective} defines the behavior common to nodes that represent
+ * The abstract class `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>
+ * directive ::=[ExportDirective exportDirective]| [ImportDirective importDirective]</pre>
  * @coverage dart.engine.ast
  */
 abstract class NamespaceDirective extends UriBasedDirective {
@@ -9143,11 +9143,11 @@
   Token get firstTokenAfterCommentAndMetadata => _keyword;
 }
 /**
- * Instances of the class {@code NativeFunctionBody} represent a function body that consists of a
+ * Instances of the class `NativeFunctionBody` represent a function body that consists of a
  * native keyword followed by a string literal.
  * <pre>
  * nativeFunctionBody ::=
- * 'native' {@link SimpleStringLiteral simpleStringLiteral} ';'
+ * 'native' [SimpleStringLiteral simpleStringLiteral] ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -9215,16 +9215,16 @@
   }
 }
 /**
- * The abstract class {@code NormalFormalParameter} defines the behavior common to formal parameters
+ * The abstract class `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>
+ * normalFormalParameter ::=[FunctionTypedFormalParameter functionSignature]| [FieldFormalParameter fieldFormalParameter]| [SimpleFormalParameter simpleFormalParameter]</pre>
  * @coverage dart.engine.ast
  */
 abstract class NormalFormalParameter extends FormalParameter {
 
   /**
-   * The documentation comment associated with this parameter, or {@code null} if this parameter
+   * The documentation comment associated with this parameter, or `null` if this parameter
    * does not have a documentation comment associated with it.
    */
   Comment _comment;
@@ -9261,7 +9261,7 @@
   NormalFormalParameter({Comment comment, List<Annotation> metadata, SimpleIdentifier identifier}) : this.full(comment, metadata, identifier);
 
   /**
-   * Return the documentation comment associated with this parameter, or {@code null} if this
+   * Return the documentation comment associated with this parameter, or `null` if this
    * parameter does not have a documentation comment associated with it.
    * @return the documentation comment associated with this parameter
    */
@@ -9282,18 +9282,18 @@
   NodeList<Annotation> get metadata => _metadata;
 
   /**
-   * Return {@code true} if this parameter was declared with the 'const' modifier.
-   * @return {@code true} if this parameter was declared with the 'const' modifier
+   * Return `true` if this parameter was declared with the 'const' modifier.
+   * @return `true` if this parameter was declared with the 'const' modifier
    */
-  bool isConst();
+  bool get isConst;
 
   /**
-   * Return {@code true} if this parameter was declared with the 'final' modifier. Parameters that
-   * are declared with the 'const' modifier will return {@code false} even though they are
+   * Return `true` if this parameter was declared with the 'final' modifier. Parameters that
+   * are declared with the 'const' modifier will return `false` even though they are
    * implicitly final.
-   * @return {@code true} if this parameter was declared with the 'final' modifier
+   * @return `true` if this parameter was declared with the 'final' modifier
    */
-  bool isFinal();
+  bool get isFinal;
 
   /**
    * Set the documentation comment associated with this parameter to the given comment
@@ -9322,8 +9322,8 @@
   }
 
   /**
-   * Return {@code true} if the comment is lexically before any annotations.
-   * @return {@code true} if the comment is lexically before any annotations
+   * Return `true` if the comment is lexically before any annotations.
+   * @return `true` if the comment is lexically before any annotations
    */
   bool commentIsBeforeAnnotations() {
     if (_comment == null || _metadata.isEmpty) {
@@ -9349,7 +9349,7 @@
   }
 }
 /**
- * Instances of the class {@code NullLiteral} represent a null literal expression.
+ * Instances of the class `NullLiteral` represent a null literal expression.
  * <pre>
  * nullLiteral ::=
  * 'null'
@@ -9397,10 +9397,10 @@
   }
 }
 /**
- * Instances of the class {@code ParenthesizedExpression} represent a parenthesized expression.
+ * Instances of the class `ParenthesizedExpression` represent a parenthesized expression.
  * <pre>
  * parenthesizedExpression ::=
- * '(' {@link Expression expression} ')'
+ * '(' [Expression expression] ')'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -9490,9 +9490,9 @@
   }
 }
 /**
- * Instances of the class {@code PartDirective} represent a part directive.
+ * Instances of the class `PartDirective` represent a part directive.
  * <pre>
- * partDirective ::={@link Annotation metadata} 'part' {@link StringLiteral partUri} ';'
+ * partDirective ::=[Annotation metadata] 'part' [StringLiteral partUri] ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -9565,9 +9565,9 @@
   Token get firstTokenAfterCommentAndMetadata => _partToken;
 }
 /**
- * Instances of the class {@code PartOfDirective} represent a part-of directive.
+ * Instances of the class `PartOfDirective` represent a part-of directive.
  * <pre>
- * partOfDirective ::={@link Annotation metadata} 'part' 'of' {@link Identifier libraryName} ';'
+ * partOfDirective ::=[Annotation metadata] 'part' 'of' [Identifier libraryName] ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -9685,9 +9685,9 @@
   Token get firstTokenAfterCommentAndMetadata => _partToken;
 }
 /**
- * Instances of the class {@code PostfixExpression} represent a postfix unary expression.
+ * Instances of the class `PostfixExpression` represent a postfix unary expression.
  * <pre>
- * postfixExpression ::={@link Expression operand} {@link Token operator}</pre>
+ * postfixExpression ::=[Expression operand] [Token operator]</pre>
  * @coverage dart.engine.ast
  */
 class PostfixExpression extends Expression {
@@ -9703,13 +9703,13 @@
   Token _operator;
 
   /**
-   * The element associated with this the operator based on the propagated type of the operand, or{@code null} if the AST structure has not been resolved, if the operator is not user definable,
+   * The element associated with this the operator based on the propagated type of the operand, or`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 _propagatedElement;
 
   /**
-   * The element associated with the operator based on the static type of the operand, or{@code null} if the AST structure has not been resolved, if the operator is not user definable,
+   * The element associated with the operator based on the static type of the operand, or`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 _staticElement;
@@ -9734,7 +9734,7 @@
   Token get beginToken => _operand.beginToken;
 
   /**
-   * Return the element associated with the operator based on the propagated type of the operand, or{@code null} if the AST structure has not been resolved, if the operator is not user definable,
+   * Return the element associated with the operator based on the propagated type of the operand, or`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
@@ -9755,7 +9755,7 @@
   Token get operator => _operator;
 
   /**
-   * Return the element associated with the operator based on the static type of the operand, or{@code null} if the AST structure has not been resolved, if the operator is not user definable,
+   * Return the element associated with the operator based on the static type of the operand, or`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
@@ -9802,9 +9802,9 @@
   /**
    * If the AST structure has been resolved, and the function being invoked is known based on
    * propagated type information, then return the parameter element representing the parameter to
-   * which the value of the operand will be bound. Otherwise, return {@code null}.
-   * <p>
-   * This method is only intended to be used by {@link Expression#getParameterElement()}.
+   * which the value of the operand will be bound. Otherwise, return `null`.
+   *
+   * This method is only intended to be used by [Expression#getParameterElement].
    * @return the parameter element representing the parameter to which the value of the right
    * operand will be bound
    */
@@ -9822,9 +9822,9 @@
   /**
    * If the AST structure has been resolved, and the function being invoked is known based on static
    * type information, then return the parameter element representing the parameter to which the
-   * value of the operand will be bound. Otherwise, return {@code null}.
-   * <p>
-   * This method is only intended to be used by {@link Expression#getStaticParameterElement()}.
+   * value of the operand will be bound. Otherwise, return `null`.
+   *
+   * This method is only intended to be used by [Expression#getStaticParameterElement].
    * @return the parameter element representing the parameter to which the value of the right
    * operand will be bound
    */
@@ -9840,9 +9840,9 @@
   }
 }
 /**
- * Instances of the class {@code PrefixExpression} represent a prefix unary expression.
+ * Instances of the class `PrefixExpression` represent a prefix unary expression.
  * <pre>
- * prefixExpression ::={@link Token operator} {@link Expression operand}</pre>
+ * prefixExpression ::=[Token operator] [Expression operand]</pre>
  * @coverage dart.engine.ast
  */
 class PrefixExpression extends Expression {
@@ -9858,13 +9858,13 @@
   Expression _operand;
 
   /**
-   * The element associated with the operator based on the static type of the operand, or{@code null} if the AST structure has not been resolved, if the operator is not user definable,
+   * The element associated with the operator based on the static type of the operand, or`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 _staticElement;
 
   /**
-   * The element associated with the operator based on the propagated type of the operand, or{@code null} if the AST structure has not been resolved, if the operator is not user definable,
+   * The element associated with the operator based on the propagated type of the operand, or`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 _propagatedElement;
@@ -9889,7 +9889,7 @@
   Token get beginToken => _operator;
 
   /**
-   * Return the element associated with the operator based on the propagated type of the operand, or{@code null} if the AST structure has not been resolved, if the operator is not user definable,
+   * Return the element associated with the operator based on the propagated type of the operand, or`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
@@ -9910,7 +9910,7 @@
   Token get operator => _operator;
 
   /**
-   * Return the element associated with the operator based on the static type of the operand, or{@code null} if the AST structure has not been resolved, if the operator is not user definable,
+   * Return the element associated with the operator based on the static type of the operand, or`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
@@ -9957,9 +9957,9 @@
   /**
    * If the AST structure has been resolved, and the function being invoked is known based on
    * propagated type information, then return the parameter element representing the parameter to
-   * which the value of the operand will be bound. Otherwise, return {@code null}.
-   * <p>
-   * This method is only intended to be used by {@link Expression#getParameterElement()}.
+   * which the value of the operand will be bound. Otherwise, return `null`.
+   *
+   * This method is only intended to be used by [Expression#getParameterElement].
    * @return the parameter element representing the parameter to which the value of the right
    * operand will be bound
    */
@@ -9977,9 +9977,9 @@
   /**
    * If the AST structure has been resolved, and the function being invoked is known based on static
    * type information, then return the parameter element representing the parameter to which the
-   * value of the operand will be bound. Otherwise, return {@code null}.
-   * <p>
-   * This method is only intended to be used by {@link Expression#getStaticParameterElement()}.
+   * value of the operand will be bound. Otherwise, return `null`.
+   *
+   * This method is only intended to be used by [Expression#getStaticParameterElement].
    * @return the parameter element representing the parameter to which the value of the right
    * operand will be bound
    */
@@ -9995,11 +9995,11 @@
   }
 }
 /**
- * Instances of the class {@code PrefixedIdentifier} represent either an identifier that is prefixed
+ * Instances of the class `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>
+ * prefixedIdentifier ::=[SimpleIdentifier prefix] '.' [SimpleIdentifier identifier]</pre>
  * @coverage dart.engine.ast
  */
 class PrefixedIdentifier extends Identifier {
@@ -10103,12 +10103,12 @@
   }
 }
 /**
- * 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
+ * Instances of the class `PropertyAccess` represent the access of a property of an object.
+ *
+ * Note, however, that accesses to properties of objects can also be represented as[PrefixedIdentifier prefixed identifier] nodes in cases where the target is also a simple
  * identifier.
  * <pre>
- * propertyAccess ::={@link Expression target} '.' {@link SimpleIdentifier propertyName}</pre>
+ * propertyAccess ::=[Expression target] '.' [SimpleIdentifier propertyName]</pre>
  * @coverage dart.engine.ast
  */
 class PropertyAccess extends Expression {
@@ -10170,14 +10170,14 @@
 
   /**
    * 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
+   * part of a cascade expression, then this is the same as [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()) {
+    if (isCascaded) {
       ASTNode ancestor = parent;
       while (ancestor is! CascadeExpression) {
         if (ancestor == null) {
@@ -10191,19 +10191,19 @@
   }
 
   /**
-   * 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, or`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;
+  bool get 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
+   * Return `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[CascadeExpression].
+   * @return `true` if this expression is cascaded
    */
-  bool isCascaded() => _operator != null && identical(_operator.type, TokenType.PERIOD_PERIOD);
+  bool get isCascaded => _operator != null && identical(_operator.type, TokenType.PERIOD_PERIOD);
 
   /**
    * Set the property access operator to the given token.
@@ -10235,7 +10235,7 @@
   }
 }
 /**
- * Instances of the class {@code RedirectingConstructorInvocation} represent the invocation of a
+ * Instances of the class `RedirectingConstructorInvocation` represent the invocation of a
  * another constructor in the same class from within a constructor's initialization list.
  * <pre>
  * redirectingConstructorInvocation ::=
@@ -10251,12 +10251,12 @@
   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.
+   * The token for the period before the name of the constructor that is being invoked, or`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
+   * The name of the constructor that is being invoked, or `null` if the unnamed constructor
    * is being invoked.
    */
   SimpleIdentifier _constructorName;
@@ -10267,12 +10267,12 @@
   ArgumentList _argumentList;
 
   /**
-   * The element associated with the constructor based on static type information, or {@code null}if the AST structure has not been resolved or if the constructor could not be resolved.
+   * The element associated with the constructor based on static type information, or `null`if the AST structure has not been resolved or if the constructor could not be resolved.
    */
   ConstructorElement _staticElement;
 
   /**
-   * The element associated with the constructor based on propagated type information, or{@code null} if the AST structure has not been resolved or if the constructor could not be
+   * The element associated with the constructor based on propagated type information, or`null` if the AST structure has not been resolved or if the constructor could not be
    * resolved.
    */
   ConstructorElement _propagatedElement;
@@ -10311,14 +10311,14 @@
   Token get beginToken => _keyword;
 
   /**
-   * Return the name of the constructor that is being invoked, or {@code null} if the unnamed
+   * Return the name of the constructor that is being invoked, or `null` if the unnamed
    * constructor is being invoked.
    * @return the name of the constructor that is being invoked
    */
   SimpleIdentifier get constructorName => _constructorName;
 
   /**
-   * Return the element associated with the constructor based on propagated type information, or{@code null} if the AST structure has not been resolved or if the constructor could not be
+   * Return the element associated with the constructor based on propagated type information, or`null` if the AST structure has not been resolved or if the constructor could not be
    * resolved.
    * @return the element associated with the super constructor
    */
@@ -10332,13 +10332,13 @@
   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, or`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;
 
   /**
-   * Return the element associated with the constructor based on static type information, or{@code null} if the AST structure has not been resolved or if the constructor could not be
+   * Return the element associated with the constructor based on static type information, or`null` if the AST structure has not been resolved or if the constructor could not be
    * resolved.
    * @return the element associated with the constructor
    */
@@ -10400,7 +10400,7 @@
   }
 }
 /**
- * Instances of the class {@code RethrowExpression} represent a rethrow expression.
+ * Instances of the class `RethrowExpression` represent a rethrow expression.
  * <pre>
  * rethrowExpression ::=
  * 'rethrow'
@@ -10448,10 +10448,10 @@
   }
 }
 /**
- * Instances of the class {@code ReturnStatement} represent a return statement.
+ * Instances of the class `ReturnStatement` represent a return statement.
  * <pre>
  * returnStatement ::=
- * 'return' {@link Expression expression}? ';'
+ * 'return' [Expression expression]? ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -10463,7 +10463,7 @@
   Token _keyword;
 
   /**
-   * The expression computing the value to be returned, or {@code null} if no explicit value was
+   * The expression computing the value to be returned, or `null` if no explicit value was
    * provided.
    */
   Expression _expression;
@@ -10497,7 +10497,7 @@
   Token get endToken => _semicolon;
 
   /**
-   * Return the expression computing the value to be returned, or {@code null} if no explicit value
+   * Return the expression computing the value to be returned, or `null` if no explicit value
    * was provided.
    * @return the expression computing the value to be returned
    */
@@ -10543,7 +10543,7 @@
   }
 }
 /**
- * Instances of the class {@code ScriptTag} represent the script tag that can optionally occur at
+ * Instances of the class `ScriptTag` represent the script tag that can optionally occur at
  * the beginning of a compilation unit.
  * <pre>
  * scriptTag ::=
@@ -10592,11 +10592,11 @@
   }
 }
 /**
- * Instances of the class {@code ShowCombinator} represent a combinator that restricts the names
+ * Instances of the class `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})
+ * 'show' [SimpleIdentifier identifier] (',' [SimpleIdentifier identifier])
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -10636,22 +10636,22 @@
   }
 }
 /**
- * Instances of the class {@code SimpleFormalParameter} represent a simple formal parameter.
+ * Instances of the class `SimpleFormalParameter` represent a simple formal parameter.
  * <pre>
  * simpleFormalParameter ::=
- * ('final' {@link TypeName type} | 'var' | {@link TypeName type})? {@link SimpleIdentifier identifier}</pre>
+ * ('final' [TypeName type] | 'var' | [TypeName type])? [SimpleIdentifier identifier]</pre>
  * @coverage dart.engine.ast
  */
 class SimpleFormalParameter extends NormalFormalParameter {
 
   /**
-   * The token representing either the 'final', 'const' or 'var' keyword, or {@code null} if no
+   * The token representing either the 'final', 'const' or 'var' keyword, or `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
+   * The name of the declared type of the parameter, or `null` if the parameter does not have
    * a declared type.
    */
   TypeName _type;
@@ -10696,13 +10696,13 @@
   Token get keyword => _keyword;
 
   /**
-   * Return the name of the declared type of the parameter, or {@code null} if the parameter does
+   * Return the name of the declared type of the parameter, or `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) && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
-  bool isFinal() => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.FINAL);
+  bool get isConst => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
+  bool get isFinal => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.FINAL);
 
   /**
    * Set the token representing either the 'final', 'const' or 'var' keyword to the given token.
@@ -10726,7 +10726,7 @@
   }
 }
 /**
- * Instances of the class {@code SimpleIdentifier} represent a simple identifier.
+ * Instances of the class `SimpleIdentifier` represent a simple identifier.
  * <pre>
  * simpleIdentifier ::=
  * initialCharacter internalCharacter
@@ -10743,12 +10743,12 @@
   Token _token;
 
   /**
-   * The element associated with this identifier based on static type information, or {@code null}if the AST structure has not been resolved or if this identifier could not be resolved.
+   * The element associated with this identifier based on static type information, or `null`if the AST structure has not been resolved or if this identifier could not be resolved.
    */
   Element _staticElement;
 
   /**
-   * The element associated with this identifier based on propagated type information, or{@code null} if the AST structure has not been resolved or if this identifier could not be
+   * The element associated with this identifier based on propagated type information, or`null` if the AST structure has not been resolved or if this identifier could not be
    * resolved.
    */
   Element _propagatedElement;
@@ -10780,8 +10780,8 @@
   Token get token => _token;
 
   /**
-   * Return {@code true} if this identifier is the name being declared in a declaration.
-   * @return {@code true} if this identifier is the name being declared in a declaration
+   * Return `true` if this identifier is the name being declared in a declaration.
+   * @return `true` if this identifier is the name being declared in a declaration
    */
   bool inDeclarationContext() {
     ASTNode parent = this.parent;
@@ -10813,11 +10813,11 @@
   }
 
   /**
-   * 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
+   * Return `true` if this expression is computing a right-hand value.
+   *
+   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor are
+   * they mutually exclusive. In other words, it is possible for both methods to return `true`when invoked on the same node.
+   * @return `true` if this expression is in a context where a getter will be invoked
    */
   bool inGetterContext() {
     ASTNode parent = this.parent;
@@ -10850,11 +10850,11 @@
   }
 
   /**
-   * 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
+   * Return `true` if this expression is computing a left-hand value.
+   *
+   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor are
+   * they mutually exclusive. In other words, it is possible for both methods to return `true`when invoked on the same node.
+   * @return `true` if this expression is in a context where a setter will be invoked
    */
   bool inSetterContext() {
     ASTNode parent = this.parent;
@@ -10875,7 +10875,7 @@
       target = access;
     }
     if (parent is PrefixExpression) {
-      return ((parent as PrefixExpression)).operator.type.isIncrementOperator();
+      return ((parent as PrefixExpression)).operator.type.isIncrementOperator;
     } else if (parent is PostfixExpression) {
       return true;
     } else if (parent is AssignmentExpression) {
@@ -10883,7 +10883,7 @@
     }
     return false;
   }
-  bool isSynthetic() => _token.isSynthetic();
+  bool get isSynthetic => _token.isSynthetic;
 
   /**
    * Set the element associated with this identifier based on propagated type information to the
@@ -10914,7 +10914,7 @@
   }
 }
 /**
- * Instances of the class {@code SimpleStringLiteral} represent a string literal expression that
+ * Instances of the class `SimpleStringLiteral` represent a string literal expression that
  * does not contain any interpolations.
  * <pre>
  * simpleStringLiteral ::=
@@ -10979,10 +10979,10 @@
   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
+   * Return `true` if this string literal is a multi-line string.
+   * @return `true` if this string literal is a multi-line string
    */
-  bool isMultiline() {
+  bool get isMultiline {
     if (_value.length < 6) {
       return false;
     }
@@ -10990,11 +10990,11 @@
   }
 
   /**
-   * Return {@code true} if this string literal is a raw string.
-   * @return {@code true} if this string literal is a raw string
+   * Return `true` if this string literal is a raw string.
+   * @return `true` if this string literal is a raw string
    */
-  bool isRaw() => _value.codeUnitAt(0) == 0x40;
-  bool isSynthetic() => _literal.isSynthetic();
+  bool get isRaw => _value.codeUnitAt(0) == 0x40;
+  bool get isSynthetic => _literal.isSynthetic;
 
   /**
    * Set the token representing the literal to the given token.
@@ -11018,20 +11018,20 @@
   }
 }
 /**
- * Instances of the class {@code Statement} defines the behavior common to nodes that represent a
+ * Instances of the class `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>
+ * statement ::=[Block block]| [VariableDeclarationStatement initializedVariableDeclaration ';']| [ForStatement forStatement]| [ForEachStatement forEachStatement]| [WhileStatement whileStatement]| [DoStatement doStatement]| [SwitchStatement switchStatement]| [IfStatement ifStatement]| [TryStatement tryStatement]| [BreakStatement breakStatement]| [ContinueStatement continueStatement]| [ReturnStatement returnStatement]| [ExpressionStatement expressionStatement]| [FunctionDeclarationStatement functionSignature functionBody]</pre>
  * @coverage dart.engine.ast
  */
 abstract class Statement extends ASTNode {
 }
 /**
- * Instances of the class {@code StringInterpolation} represent a string interpolation literal.
+ * Instances of the class `StringInterpolation` represent a string interpolation literal.
  * <pre>
  * stringInterpolation ::=
- * ''' {@link InterpolationElement interpolationElement}* '''
- * | '"' {@link InterpolationElement interpolationElement}* '"'
+ * ''' [InterpolationElement interpolationElement]* '''
+ * | '"' [InterpolationElement interpolationElement]* '"'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -11073,15 +11073,15 @@
   }
 }
 /**
- * Instances of the class {@code StringLiteral} represent a string literal expression.
+ * Instances of the class `StringLiteral` represent a string literal expression.
  * <pre>
- * stringLiteral ::={@link SimpleStringLiteral simpleStringLiteral}| {@link AdjacentStrings adjacentStrings}| {@link StringInterpolation stringInterpolation}</pre>
+ * stringLiteral ::=[SimpleStringLiteral simpleStringLiteral]| [AdjacentStrings adjacentStrings]| [StringInterpolation stringInterpolation]</pre>
  * @coverage dart.engine.ast
  */
 abstract class StringLiteral extends Literal {
 
   /**
-   * Return the value of the string literal, or {@code null} if the string is not a constant string
+   * Return the value of the string literal, or `null` if the string is not a constant string
    * without any string interpolation.
    * @return the value of the string literal
    */
@@ -11104,11 +11104,11 @@
   void appendStringValue(JavaStringBuilder builder);
 }
 /**
- * Instances of the class {@code SuperConstructorInvocation} represent the invocation of a
+ * Instances of the class `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>
+ * 'super' ('.' [SimpleIdentifier name])? [ArgumentList argumentList]</pre>
  * @coverage dart.engine.ast
  */
 class SuperConstructorInvocation extends ConstructorInitializer {
@@ -11119,12 +11119,12 @@
   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.
+   * The token for the period before the name of the constructor that is being invoked, or`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
+   * The name of the constructor that is being invoked, or `null` if the unnamed constructor
    * is being invoked.
    */
   SimpleIdentifier _constructorName;
@@ -11135,12 +11135,12 @@
   ArgumentList _argumentList;
 
   /**
-   * The element associated with the constructor based on static type information, or {@code null}if the AST structure has not been resolved or if the constructor could not be resolved.
+   * The element associated with the constructor based on static type information, or `null`if the AST structure has not been resolved or if the constructor could not be resolved.
    */
   ConstructorElement _staticElement;
 
   /**
-   * The element associated with the constructor based on propagated type information, or {@code null} if the AST structure has not been
+   * The element associated with the constructor based on propagated type information, or `null` if the AST structure has not been
    * resolved or if the constructor could not be resolved.
    */
   ConstructorElement _propagatedElement;
@@ -11179,14 +11179,14 @@
   Token get beginToken => _keyword;
 
   /**
-   * Return the name of the constructor that is being invoked, or {@code null} if the unnamed
+   * Return the name of the constructor that is being invoked, or `null` if the unnamed
    * constructor is being invoked.
    * @return the name of the constructor that is being invoked
    */
   SimpleIdentifier get constructorName => _constructorName;
 
   /**
-   * Return the element associated with the constructor based on propagated type information, or{@code null} if the AST structure has not been resolved or if the constructor could not be
+   * Return the element associated with the constructor based on propagated type information, or`null` if the AST structure has not been resolved or if the constructor could not be
    * resolved.
    * @return the element associated with the super constructor
    */
@@ -11200,13 +11200,13 @@
   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, or`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;
 
   /**
-   * Return the element associated with the constructor based on static type information, or{@code null} if the AST structure has not been resolved or if the constructor could not be
+   * Return the element associated with the constructor based on static type information, or`null` if the AST structure has not been resolved or if the constructor could not be
    * resolved.
    * @return the element associated with the constructor
    */
@@ -11268,7 +11268,7 @@
   }
 }
 /**
- * Instances of the class {@code SuperExpression} represent a super expression.
+ * Instances of the class `SuperExpression` represent a super expression.
  * <pre>
  * superExpression ::=
  * 'super'
@@ -11316,9 +11316,9 @@
   }
 }
 /**
- * Instances of the class {@code SwitchCase} represent the case in a switch statement.
+ * Instances of the class `SwitchCase` represent the case in a switch statement.
  * <pre>
- * switchCase ::={@link SimpleIdentifier label}* 'case' {@link Expression expression} ':' {@link Statement statement}</pre>
+ * switchCase ::=[SimpleIdentifier label]* 'case' [Expression expression] ':' [Statement statement]</pre>
  * @coverage dart.engine.ast
  */
 class SwitchCase extends SwitchMember {
@@ -11371,9 +11371,9 @@
   }
 }
 /**
- * Instances of the class {@code SwitchDefault} represent the default case in a switch statement.
+ * Instances of the class `SwitchDefault` represent the default case in a switch statement.
  * <pre>
- * switchDefault ::={@link SimpleIdentifier label}* 'default' ':' {@link Statement statement}</pre>
+ * switchDefault ::=[SimpleIdentifier label]* 'default' ':' [Statement statement]</pre>
  * @coverage dart.engine.ast
  */
 class SwitchDefault extends SwitchMember {
@@ -11403,7 +11403,7 @@
   }
 }
 /**
- * The abstract class {@code SwitchMember} defines the behavior common to objects representing
+ * The abstract class `SwitchMember` defines the behavior common to objects representing
  * elements within a switch statement.
  * <pre>
  * switchMember ::=
@@ -11512,10 +11512,10 @@
   }
 }
 /**
- * Instances of the class {@code SwitchStatement} represent a switch statement.
+ * Instances of the class `SwitchStatement` represent a switch statement.
  * <pre>
  * switchStatement ::=
- * 'switch' '(' {@link Expression expression} ')' '{' {@link SwitchCase switchCase}* {@link SwitchDefault defaultCase}? '}'
+ * 'switch' '(' [Expression expression] ')' '{' [SwitchCase switchCase]* [SwitchDefault defaultCase]? '}'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -11688,7 +11688,7 @@
   }
 }
 /**
- * Instances of the class {@code ThisExpression} represent a this expression.
+ * Instances of the class `ThisExpression` represent a this expression.
  * <pre>
  * thisExpression ::=
  * 'this'
@@ -11736,10 +11736,10 @@
   }
 }
 /**
- * Instances of the class {@code ThrowExpression} represent a throw expression.
+ * Instances of the class `ThrowExpression` represent a throw expression.
  * <pre>
  * throwExpression ::=
- * 'throw' {@link Expression expression}</pre>
+ * 'throw' [Expression expression]</pre>
  * @coverage dart.engine.ast
  */
 class ThrowExpression extends Expression {
@@ -11811,7 +11811,7 @@
   }
 }
 /**
- * Instances of the class {@code TopLevelVariableDeclaration} represent the declaration of one or
+ * Instances of the class `TopLevelVariableDeclaration` represent the declaration of one or
  * more top-level variables of the same type.
  * <pre>
  * topLevelVariableDeclaration ::=
@@ -11890,12 +11890,12 @@
   Token get firstTokenAfterCommentAndMetadata => _variableList.beginToken;
 }
 /**
- * Instances of the class {@code TryStatement} represent a try statement.
+ * Instances of the class `TryStatement` represent a try statement.
  * <pre>
  * tryStatement ::=
- * 'try' {@link Block block} ({@link CatchClause catchClause}+ finallyClause? | finallyClause)
+ * 'try' [Block block] ([CatchClause catchClause]+ finallyClause? | finallyClause)
  * finallyClause ::=
- * 'finally' {@link Block block}</pre>
+ * 'finally' [Block block]</pre>
  * @coverage dart.engine.ast
  */
 class TryStatement extends Statement {
@@ -11916,13 +11916,13 @@
   NodeList<CatchClause> _catchClauses;
 
   /**
-   * The token representing the 'finally' keyword, or {@code null} if the statement does not contain
+   * The token representing the 'finally' keyword, or `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
+   * The finally clause contained in the try statement, or `null` if the statement does not
    * contain a finally clause.
    */
   Block _finallyClause;
@@ -11979,14 +11979,14 @@
   }
 
   /**
-   * Return the finally clause contained in the try statement, or {@code null} if the statement does
+   * Return the finally clause contained in the try statement, or `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
+   * Return the token representing the 'finally' keyword, or `null` if the statement does not
    * contain a finally clause.
    * @return the token representing the 'finally' keyword
    */
@@ -12036,7 +12036,7 @@
   }
 }
 /**
- * The abstract class {@code TypeAlias} defines the behavior common to declarations of type aliases.
+ * The abstract class `TypeAlias` defines the behavior common to declarations of type aliases.
  * <pre>
  * typeAlias ::=
  * 'typedef' typeAliasBody
@@ -12110,7 +12110,7 @@
   Token get firstTokenAfterCommentAndMetadata => _keyword;
 }
 /**
- * Instances of the class {@code TypeArgumentList} represent a list of type arguments.
+ * Instances of the class `TypeArgumentList` represent a list of type arguments.
  * <pre>
  * typeArguments ::=
  * '<' typeName (',' typeName)* '>'
@@ -12196,10 +12196,10 @@
   }
 }
 /**
- * Instances of the class {@code TypeName} represent the name of a type, which can optionally
+ * Instances of the class `TypeName` represent the name of a type, which can optionally
  * include type arguments.
  * <pre>
- * typeName ::={@link Identifier identifier} typeArguments?
+ * typeName ::=[Identifier identifier] typeArguments?
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -12211,19 +12211,19 @@
   Identifier _name;
 
   /**
-   * The type arguments associated with the type, or {@code null} if there are no type arguments.
+   * The type arguments associated with the type, or `null` if there are no type arguments.
    */
   TypeArgumentList _typeArguments;
 
   /**
-   * The type being named, or {@code null} if the AST structure has not been resolved.
+   * The type being named, or `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
+   * @param typeArguments the type arguments associated with the type, or `null` if there are
    * no type arguments
    */
   TypeName.full(Identifier name, TypeArgumentList typeArguments) {
@@ -12234,7 +12234,7 @@
   /**
    * 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
+   * @param typeArguments the type arguments associated with the type, or `null` if there are
    * no type arguments
    */
   TypeName({Identifier name, TypeArgumentList typeArguments}) : this.full(name, typeArguments);
@@ -12254,18 +12254,18 @@
   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, or `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
+   * Return the type arguments associated with the type, or `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;
+  bool get isSynthetic => _name.isSynthetic && _typeArguments == null;
 
   /**
    * Set the name of the type to the given identifier.
@@ -12296,9 +12296,9 @@
   }
 }
 /**
- * Instances of the class {@code TypeParameter} represent a type parameter.
+ * Instances of the class `TypeParameter` represent a type parameter.
  * <pre>
- * typeParameter ::={@link SimpleIdentifier name} ('extends' {@link TypeName bound})?
+ * typeParameter ::=[SimpleIdentifier name] ('extends' [TypeName bound])?
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -12310,13 +12310,13 @@
   SimpleIdentifier _name;
 
   /**
-   * The token representing the 'extends' keyword, or {@code null} if there was no explicit upper
+   * The token representing the 'extends' keyword, or `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
+   * The name of the upper bound for legal arguments, or `null` if there was no explicit upper
    * bound.
    */
   TypeName _bound;
@@ -12347,7 +12347,7 @@
   accept(ASTVisitor visitor) => visitor.visitTypeParameter(this);
 
   /**
-   * Return the name of the upper bound for legal arguments, or {@code null} if there was no
+   * Return the name of the upper bound for legal arguments, or `null` if there was no
    * explicit upper bound.
    * @return the name of the upper bound for legal arguments
    */
@@ -12403,10 +12403,10 @@
   Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
 }
 /**
- * Instances of the class {@code TypeParameterList} represent type parameters within a declaration.
+ * Instances of the class `TypeParameterList` represent type parameters within a declaration.
  * <pre>
  * typeParameterList ::=
- * '<' {@link TypeParameter typeParameter} (',' {@link TypeParameter typeParameter})* '>'
+ * '<' [TypeParameter typeParameter] (',' [TypeParameter typeParameter])* '>'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -12473,22 +12473,22 @@
   }
 }
 /**
- * The abstract class {@code TypedLiteral} defines the behavior common to literals that have a type
+ * The abstract class `TypedLiteral` defines the behavior common to literals that have a type
  * associated with them.
  * <pre>
- * listLiteral ::={@link ListLiteral listLiteral}| {@link MapLiteral mapLiteral}</pre>
+ * listLiteral ::=[ListLiteral listLiteral]| [MapLiteral mapLiteral]</pre>
  * @coverage dart.engine.ast
  */
 abstract class TypedLiteral extends Literal {
 
   /**
-   * The const modifier associated with this literal, or {@code null} if the literal is not a
+   * The const modifier associated with this literal, or `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
+   * The type argument associated with this literal, or `null` if no type arguments were
    * declared.
    */
   TypeArgumentList _typeArguments;
@@ -12496,7 +12496,7 @@
   /**
    * 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
+   * @param typeArguments the type argument associated with this literal, or `null` if no type
    * arguments were declared
    */
   TypedLiteral.full(Token modifier, TypeArgumentList typeArguments) {
@@ -12507,7 +12507,7 @@
   /**
    * 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
+   * @param typeArguments the type argument associated with this literal, or `null` if no type
    * arguments were declared
    */
   TypedLiteral({Token modifier, TypeArgumentList typeArguments}) : this.full(modifier, typeArguments);
@@ -12519,7 +12519,7 @@
   Token get modifier => _modifier;
 
   /**
-   * Return the type argument associated with this literal, or {@code null} if no type arguments
+   * Return the type argument associated with this literal, or `null` if no type arguments
    * were declared.
    * @return the type argument associated with this literal
    */
@@ -12545,10 +12545,10 @@
   }
 }
 /**
- * The abstract class {@code UriBasedDirective} defines the behavior common to nodes that represent
+ * The abstract class `UriBasedDirective` defines the behavior common to nodes that represent
  * a directive that references a URI.
  * <pre>
- * uriBasedDirective ::={@link ExportDirective exportDirective}| {@link ImportDirective importDirective}| {@link PartDirective partDirective}</pre>
+ * uriBasedDirective ::=[ExportDirective exportDirective]| [ImportDirective importDirective]| [PartDirective partDirective]</pre>
  * @coverage dart.engine.ast
  */
 abstract class UriBasedDirective extends Directive {
@@ -12583,7 +12583,7 @@
   StringLiteral get uri => _uri;
 
   /**
-   * Return the element associated with the URI of this directive, or {@code null} if the AST
+   * Return the element associated with the URI of this directive, or `null` if the AST
    * structure has not been resolved or if this URI 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
@@ -12603,10 +12603,10 @@
   }
 }
 /**
- * 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}.
+ * Instances of the class `VariableDeclaration` represent an identifier that has an initial
+ * value associated with it. Instances of this class are always children of the class[VariableDeclarationList].
  * <pre>
- * variableDeclaration ::={@link SimpleIdentifier identifier} ('=' {@link Expression initialValue})?
+ * variableDeclaration ::=[SimpleIdentifier identifier] ('=' [Expression initialValue])?
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -12618,13 +12618,13 @@
   SimpleIdentifier _name;
 
   /**
-   * The equal sign separating the variable name from the initial value, or {@code null} if the
+   * The equal sign separating the variable name from the initial value, or `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
+   * The expression used to compute the initial value for the variable, or `null` if the
    * initial value was not specified.
    */
   Expression _initializer;
@@ -12679,14 +12679,14 @@
   }
 
   /**
-   * Return the equal sign separating the variable name from the initial value, or {@code null} if
+   * Return the equal sign separating the variable name from the initial value, or `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
+   * Return the expression used to compute the initial value for the variable, or `null` if
    * the initial value was not specified.
    * @return the expression used to compute the initial value for the variable
    */
@@ -12699,23 +12699,23 @@
   SimpleIdentifier get name => _name;
 
   /**
-   * Return {@code true} if this variable was declared with the 'const' modifier.
-   * @return {@code true} if this variable was declared with the 'const' modifier
+   * Return `true` if this variable was declared with the 'const' modifier.
+   * @return `true` if this variable was declared with the 'const' modifier
    */
-  bool isConst() {
+  bool get isConst {
     ASTNode parent = this.parent;
-    return parent is VariableDeclarationList && ((parent as VariableDeclarationList)).isConst();
+    return parent is VariableDeclarationList && ((parent as VariableDeclarationList)).isConst;
   }
 
   /**
-   * Return {@code true} if this variable was declared with the 'final' modifier. Variables that are
-   * declared with the 'const' modifier will return {@code false} even though they are implicitly
+   * Return `true` if this variable was declared with the 'final' modifier. Variables that are
+   * declared with the 'const' modifier will return `false` even though they are implicitly
    * final.
-   * @return {@code true} if this variable was declared with the 'final' modifier
+   * @return `true` if this variable was declared with the 'final' modifier
    */
-  bool isFinal() {
+  bool get isFinal {
     ASTNode parent = this.parent;
-    return parent is VariableDeclarationList && ((parent as VariableDeclarationList)).isFinal();
+    return parent is VariableDeclarationList && ((parent as VariableDeclarationList)).isFinal;
   }
 
   /**
@@ -12749,28 +12749,28 @@
   Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
 }
 /**
- * Instances of the class {@code VariableDeclarationList} represent the declaration of one or more
+ * Instances of the class `VariableDeclarationList` represent the declaration of one or more
  * variables of the same type.
  * <pre>
  * variableDeclarationList ::=
- * finalConstVarOrType {@link VariableDeclaration variableDeclaration} (',' {@link VariableDeclaration variableDeclaration})
+ * finalConstVarOrType [VariableDeclaration variableDeclaration] (',' [VariableDeclaration variableDeclaration])
  * finalConstVarOrType ::=
- * | 'final' {@link TypeName type}?
- * | 'const' {@link TypeName type}?
+ * | 'final' [TypeName type]?
+ * | 'const' [TypeName type]?
  * | 'var'
- * | {@link TypeName type}</pre>
+ * | [TypeName type]</pre>
  * @coverage dart.engine.ast
  */
 class VariableDeclarationList extends AnnotatedNode {
 
   /**
-   * The token representing the 'final', 'const' or 'var' keyword, or {@code null} if no keyword was
+   * The token representing the 'final', 'const' or 'var' keyword, or `null` if no keyword was
    * included.
    */
   Token _keyword;
 
   /**
-   * The type of the variables being declared, or {@code null} if no type was provided.
+   * The type of the variables being declared, or `null` if no type was provided.
    */
   TypeName _type;
 
@@ -12807,14 +12807,14 @@
   Token get endToken => _variables.endToken;
 
   /**
-   * Return the token representing the 'final', 'const' or 'var' keyword, or {@code null} if no
+   * Return the token representing the 'final', 'const' or 'var' keyword, or `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, or `null` if no type was provided.
    * @return the type of the variables being declared
    */
   TypeName get type => _type;
@@ -12826,18 +12826,18 @@
   NodeList<VariableDeclaration> get variables => _variables;
 
   /**
-   * Return {@code true} if the variables in this list were declared with the 'const' modifier.
-   * @return {@code true} if the variables in this list were declared with the 'const' modifier
+   * Return `true` if the variables in this list were declared with the 'const' modifier.
+   * @return `true` if the variables in this list were declared with the 'const' modifier
    */
-  bool isConst() => _keyword is KeywordToken && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
+  bool get isConst => _keyword is KeywordToken && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
 
   /**
-   * Return {@code true} if the variables in this list were declared with the 'final' modifier.
-   * Variables that are declared with the 'const' modifier will return {@code false} even though
+   * Return `true` if the variables in this list were declared with the 'final' modifier.
+   * Variables that are declared with the 'const' modifier will return `false` even though
    * they are implicitly final.
-   * @return {@code true} if the variables in this list were declared with the 'final' modifier
+   * @return `true` if the variables in this list were declared with the 'final' modifier
    */
-  bool isFinal() => _keyword is KeywordToken && identical(((_keyword as KeywordToken)).keyword, Keyword.FINAL);
+  bool get isFinal => _keyword is KeywordToken && identical(((_keyword as KeywordToken)).keyword, Keyword.FINAL);
 
   /**
    * Set the token representing the 'final', 'const' or 'var' keyword to the given token.
@@ -12868,10 +12868,10 @@
   }
 }
 /**
- * Instances of the class {@code VariableDeclarationStatement} represent a list of variables that
+ * Instances of the class `VariableDeclarationStatement` represent a list of variables that
  * are being declared in a context where a statement is required.
  * <pre>
- * variableDeclarationStatement ::={@link VariableDeclarationList variableList} ';'
+ * variableDeclarationStatement ::=[VariableDeclarationList variableList] ';'
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -12939,10 +12939,10 @@
   }
 }
 /**
- * Instances of the class {@code WhileStatement} represent a while statement.
+ * Instances of the class `WhileStatement` represent a while statement.
  * <pre>
  * whileStatement ::=
- * 'while' '(' {@link Expression condition} ')' {@link Statement body}</pre>
+ * 'while' '(' [Expression condition] ')' [Statement body]</pre>
  * @coverage dart.engine.ast
  */
 class WhileStatement extends Statement {
@@ -13077,10 +13077,10 @@
   }
 }
 /**
- * Instances of the class {@code WithClause} represent the with clause in a class declaration.
+ * Instances of the class `WithClause` represent the with clause in a class declaration.
  * <pre>
  * withClause ::=
- * 'with' {@link TypeName mixin} (',' {@link TypeName mixin})
+ * 'with' [TypeName mixin] (',' [TypeName mixin])
  * </pre>
  * @coverage dart.engine.ast
  */
@@ -13141,9 +13141,9 @@
   }
 }
 /**
- * Instances of the class {@code BreadthFirstVisitor} implement an AST visitor that will recursively
- * visit all of the nodes in an AST structure, similar to {@link GeneralizingASTVisitor}. This
- * visitor uses a breadth-first ordering rather than the depth-first ordering of{@link GeneralizingASTVisitor}.
+ * Instances of the class `BreadthFirstVisitor` implement an AST visitor that will recursively
+ * visit all of the nodes in an AST structure, similar to [GeneralizingASTVisitor]. This
+ * visitor uses a breadth-first ordering rather than the depth-first ordering of[GeneralizingASTVisitor].
  * @coverage dart.engine.ast
  */
 class BreadthFirstVisitor<R> extends GeneralizingASTVisitor<R> {
@@ -13151,7 +13151,7 @@
   GeneralizingASTVisitor<Object> _childVisitor;
 
   /**
-   * Visit all nodes in the tree starting at the given {@code root} node, in depth-first order.
+   * Visit all nodes in the tree starting at the given `root` node, in depth-first order.
    * @param root the root of the ASTNode tree
    */
   void visitAllNodes(ASTNode root) {
@@ -13178,32 +13178,32 @@
   }
 }
 /**
- * Instances of the class {@code ConstantEvaluator} evaluate constant expressions to produce their
+ * Instances of the class `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>
+ *
+ * * A literal number.
+ * * A literal boolean.
+ * * A literal string where any interpolated expression is a compile-time constant that evaluates
+ * to a numeric, string or boolean value or to `null`.
+ * * `null`.
+ * * A reference to a static constant variable.
+ * * An identifier expression that denotes a constant variable, a class or a type variable.
+ * * A constant constructor invocation.
+ * * A constant list literal.
+ * * A constant map literal.
+ * * A simple or qualified identifier denoting a top-level function or a static method.
+ * * A parenthesized expression `(e)` where `e` is a constant expression.
+ * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`,`e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a
+ * numeric, string or boolean value or to `null`.
+ * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where`e`, `e1` and `e2` are constant expressions that evaluate to a boolean value or
+ * to `null`.
+ * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,`e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2`are constant expressions that evaluate to an integer value or to `null`.
+ * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`,`e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`,`e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2`are constant expressions that evaluate to a numeric value or to `null`.
+ *
+ * </blockquote> The values returned by instances of this class are therefore `null` and
+ * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and`DartObject`.
+ *
  * 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.
@@ -13449,23 +13449,23 @@
   Object getConstantValue(Element element) {
     if (element is FieldElement) {
       FieldElement field = element as FieldElement;
-      if (field.isStatic() && field.isConst()) {
+      if (field.isStatic && field.isConst) {
       }
     }
     return NOT_A_CONSTANT;
   }
 }
 /**
- * Instances of the class {@code ElementLocator} locate the {@link Element Dart model element}associated with a given {@link ASTNode AST node}.
+ * Instances of the class `ElementLocator` locate the [Element Dart model element]associated with a given [ASTNode AST node].
  * @coverage dart.engine.ast
  */
 class ElementLocator {
 
   /**
-   * Locate the {@link Element Dart model element} associated with the given {@link ASTNode AST
-   * node}.
-   * @param node the node (not {@code null})
-   * @return the associated element, or {@code null} if none is found
+   * Locate the [Element Dart model element] associated with the given [ASTNode AST
+   * node].
+   * @param node the node (not `null`)
+   * @return the associated element, or `null` if none is found
    */
   static Element locate(ASTNode node) {
     ElementLocator_ElementMapper mapper = new ElementLocator_ElementMapper();
@@ -13527,15 +13527,15 @@
   Element visitVariableDeclaration(VariableDeclaration node) => node.element;
 }
 /**
- * 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
+ * Instances of the class `GeneralizingASTVisitor` implement an AST visitor that will
+ * recursively visit all of the nodes in an AST structure (like instances of the class[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
+ * visit a [Block] will cause the method [visitBlock] to be invoked but will
+ * also cause the methods [visitStatement] and [visitNode] 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>
+ * needing to override the visit method for each of the specific subclasses of [Statement].
+ *
  * 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
@@ -13671,9 +13671,9 @@
   R visitWithClause(WithClause node) => visitNode(node);
 }
 /**
- * Instances of the class {@code NodeLocator} locate the {@link ASTNode AST node} associated with a
+ * Instances of the class `NodeLocator` locate the [ASTNode AST node] associated with a
  * source range, given the AST structure built from the source. More specifically, they will return
- * the {@link ASTNode AST node} with the shortest length whose source range completely encompasses
+ * the [ASTNode AST node] with the shortest length whose source range completely encompasses
  * the specified range.
  * @coverage dart.engine.ast
  */
@@ -13690,13 +13690,13 @@
   int _endOffset = 0;
 
   /**
-   * The element that was found that corresponds to the given source range, or {@code null} if there
+   * The element that was found that corresponds to the given source range, or `null` if there
    * is no such element.
    */
   ASTNode _foundNode;
 
   /**
-   * Initialize a newly created locator to locate one or more {@link ASTNode AST nodes} by locating
+   * Initialize a newly created locator to locate one or more [ASTNode AST nodes] by locating
    * the node within an AST structure that corresponds to the given offset in the source.
    * @param offset the offset used to identify the node
    */
@@ -13708,7 +13708,7 @@
   }
 
   /**
-   * Initialize a newly created locator to locate one or more {@link ASTNode AST nodes} by locating
+   * Initialize a newly created locator to locate one or more [ASTNode AST nodes] by locating
    * the node within an AST structure that corresponds to the given range of characters in the
    * source.
    * @param start the start offset of the range used to identify the node
@@ -13723,15 +13723,15 @@
   }
 
   /**
-   * Return the node that was found that corresponds to the given source range, or {@code null} if
+   * Return the node that was found that corresponds to the given source range, or `null` if
    * there is no such node.
    * @return the node that was found
    */
   ASTNode get foundNode => _foundNode;
 
   /**
-   * Search within the given AST node for an identifier representing a {@link DartElement Dart
-   * element} in the specified source range. Return the element that was found, or {@code null} if
+   * Search within the given AST node for an identifier representing a [DartElement Dart
+   * element] in the specified source range. Return the element that was found, or `null` if
    * no element was found.
    * @param node the AST node within which to search
    * @return the element that was found
@@ -13770,17 +13770,17 @@
   }
 }
 /**
- * Instances of the class {@code NodeFoundException} are used to cancel visiting after a node has
+ * Instances of the class `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
+ * Instances of the class `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>
+ * a [Block] will also cause all of the statements in the block to be visited.
+ *
  * 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.
@@ -14193,7 +14193,7 @@
   }
 }
 /**
- * Instances of the class {@code SimpleASTVisitor} implement an AST visitor that will do nothing
+ * Instances of the class `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.
@@ -14303,7 +14303,7 @@
   R visitWithClause(WithClause node) => null;
 }
 /**
- * Instances of the class {@code ToSourceVisitor} write a source representation of a visited AST
+ * Instances of the class `ToSourceVisitor` write a source representation of a visited AST
  * node (and all of it's children) to a writer.
  * @coverage dart.engine.ast
  */
@@ -14680,7 +14680,7 @@
     return null;
   }
   Object visitIndexExpression(IndexExpression node) {
-    if (node.isCascaded()) {
+    if (node.isCascaded) {
       _writer.print("..");
     } else {
       visit(node.array);
@@ -14780,14 +14780,14 @@
     visit5(node.propertyKeyword, " ");
     visit5(node.operatorKeyword, " ");
     visit(node.name);
-    if (!node.isGetter()) {
+    if (!node.isGetter) {
       visit(node.parameters);
     }
     visit4(" ", node.body);
     return null;
   }
   Object visitMethodInvocation(MethodInvocation node) {
-    if (node.isCascaded()) {
+    if (node.isCascaded) {
       _writer.print("..");
     } else {
       visit2(node.target, ".");
@@ -14846,7 +14846,7 @@
     return null;
   }
   Object visitPropertyAccess(PropertyAccess node) {
-    if (node.isCascaded()) {
+    if (node.isCascaded) {
       _writer.print("..");
     } else {
       visit(node.target);
@@ -15017,7 +15017,7 @@
   }
 
   /**
-   * Safely visit the given node, printing the suffix after the node if it is non-{@code null}.
+   * Safely visit the given node, printing the suffix after the node if it is non-`null`.
    * @param suffix the suffix to be printed if there is a node to visit
    * @param node the node to be visited
    */
@@ -15029,7 +15029,7 @@
   }
 
   /**
-   * Safely visit the given node, printing the prefix before the node if it is non-{@code null}.
+   * Safely visit the given node, printing the prefix before the node if it is non-`null`.
    * @param prefix the prefix to be printed if there is a node to visit
    * @param node the node to be visited
    */
@@ -15053,7 +15053,7 @@
   }
 
   /**
-   * Safely visit the given node, printing the suffix after the node if it is non-{@code null}.
+   * Safely visit the given node, printing the suffix after the node if it is non-`null`.
    * @param suffix the suffix to be printed if there is a node to visit
    * @param node the node to be visited
    */
@@ -15133,7 +15133,7 @@
   }
 }
 /**
- * Instances of the class {@code ASTCloner} implement an object that will clone any AST structure
+ * Instances of the class `ASTCloner` implement an object that will clone any AST structure
  * that it visits. The cloner will only clone the structure, it will not preserve any resolution
  * results or properties associated with the nodes.
  */
@@ -15155,9 +15155,9 @@
   ClassDeclaration visitClassDeclaration(ClassDeclaration node) => new ClassDeclaration.full(clone2(node.documentationComment), clone3(node.metadata), node.abstractKeyword, node.classKeyword, clone2(node.name), clone2(node.typeParameters), clone2(node.extendsClause), clone2(node.withClause), clone2(node.implementsClause), node.leftBracket, clone3(node.members), node.rightBracket);
   ClassTypeAlias visitClassTypeAlias(ClassTypeAlias node) => new ClassTypeAlias.full(clone2(node.documentationComment), clone3(node.metadata), node.keyword, clone2(node.name), clone2(node.typeParameters), node.equals, node.abstractKeyword, clone2(node.superclass), clone2(node.withClause), clone2(node.implementsClause), node.semicolon);
   Comment visitComment(Comment node) {
-    if (node.isDocumentation()) {
+    if (node.isDocumentation) {
       return Comment.createDocumentationComment2(node.tokens, clone3(node.references));
-    } else if (node.isBlock()) {
+    } else if (node.isBlock) {
       return Comment.createBlockComment(node.tokens);
     }
     return Comment.createEndOfLineComment(node.tokens);
@@ -15277,7 +15277,7 @@
  * Traverse the AST from initial child node to successive parents, building a collection of local
  * variable and parameter names visible to the initial child node. In case of name shadowing, the
  * first name seen is the most specific one so names are not redefined.
- * <p>
+ *
  * Completion test code coverage is 95%. The two basic blocks that are not executed cannot be
  * executed. They are included for future reference.
  * @coverage com.google.dart.engine.services.completion
diff --git a/pkg/analyzer_experimental/lib/src/generated/constant.dart b/pkg/analyzer_experimental/lib/src/generated/constant.dart
index 2b39d59..294d22c 100644
--- a/pkg/analyzer_experimental/lib/src/generated/constant.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/constant.dart
@@ -9,32 +9,32 @@
 import 'element.dart';
 import 'engine.dart' show AnalysisEngine;
 /**
- * Instances of the class {@code ConstantEvaluator} evaluate constant expressions to produce their
+ * Instances of the class `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>
+ *
+ * * A literal number.
+ * * A literal boolean.
+ * * A literal string where any interpolated expression is a compile-time constant that evaluates
+ * to a numeric, string or boolean value or to `null`.
+ * * `null`.
+ * * A reference to a static constant variable.
+ * * An identifier expression that denotes a constant variable, a class or a type variable.
+ * * A constant constructor invocation.
+ * * A constant list literal.
+ * * A constant map literal.
+ * * A simple or qualified identifier denoting a top-level function or a static method.
+ * * A parenthesized expression `(e)` where `e` is a constant expression.
+ * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`,`e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a
+ * numeric, string or boolean value or to `null`.
+ * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where`e`, `e1` and `e2` are constant expressions that evaluate to a boolean value or
+ * to `null`.
+ * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,`e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2`are constant expressions that evaluate to an integer value or to `null`.
+ * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`,`e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`,`e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2`are constant expressions that evaluate to a numeric value or to `null`.
+ *
+ * </blockquote> The values returned by instances of this class are therefore `null` and
+ * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and`DartObject`.
+ *
  * 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.
@@ -67,7 +67,7 @@
   }
 }
 /**
- * Instances of the class {@code EvaluationResult} represent the result of attempting to evaluate an
+ * Instances of the class `EvaluationResult` represent the result of attempting to evaluate an
  * expression.
  */
 class EvaluationResult {
@@ -100,7 +100,7 @@
 
   /**
    * Initialize a newly created result object with the given state. Clients should use one of the
-   * factory methods: {@link #forErrors(AnalysisError\[\])} and {@link #forValue(Object)}.
+   * factory methods: [forErrors] and [forValue].
    * @param value the value of the expression
    * @param errors the errors that should be reported for the expression(s) that were evaluated
    */
@@ -118,21 +118,21 @@
   List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS : _errors;
 
   /**
-   * Return the value of the expression, or {@code null} if the expression evaluated to {@code null}or if the expression could not be evaluated, either because it was not a compile-time constant
+   * Return the value of the expression, or `null` if the expression evaluated to `null`or if the expression could not be evaluated, either because it was not a compile-time constant
    * expression or because it would throw an exception when evaluated.
    * @return the value of the expression
    */
   Object get value => _value;
 
   /**
-   * Return {@code true} if the expression is a compile-time constant expression that would not
+   * Return `true` if the expression is a compile-time constant expression that would not
    * throw an exception when evaluated.
-   * @return {@code true} if the expression is a valid compile-time constant expression
+   * @return `true` if the expression is a valid compile-time constant expression
    */
-  bool isValid() => _errors == null;
+  bool get isValid => _errors == null;
 }
 /**
- * Instances of the class {@code ConstantFinder} are used to traverse the AST structures of all of
+ * Instances of the class `ConstantFinder` are used to traverse the AST structures of all of
  * the compilation units being resolved and build a table mapping constant variable elements to the
  * declarations of those variables.
  */
@@ -151,7 +151,7 @@
   Object visitVariableDeclaration(VariableDeclaration node) {
     super.visitVariableDeclaration(node);
     Expression initializer = node.initializer;
-    if (initializer != null && node.isConst()) {
+    if (initializer != null && node.isConst) {
       VariableElement element = node.element;
       if (element != null) {
         _variableMap[element] = node;
@@ -161,10 +161,10 @@
   }
 }
 /**
- * Instances of the class {@code ConstantValueComputer} compute the values of constant variables in
+ * Instances of the class `ConstantValueComputer` compute the values of constant variables in
  * one or more compilation units. The expected usage pattern is for the compilation units to be
- * added to this computer using the method {@link #add(CompilationUnit)} and then for the method{@link #computeValues()} to invoked exactly once. Any use of an instance after invoking the
- * method {@link #computeValues()} will result in unpredictable behavior.
+ * added to this computer using the method [add] and then for the method[computeValues] to invoked exactly once. Any use of an instance after invoking the
+ * method [computeValues] will result in unpredictable behavior.
  */
 class ConstantValueComputer {
 
@@ -204,13 +204,13 @@
       _referenceGraph.addNode(element);
       entry.getValue().initializer.accept(referenceFinder);
     }
-    while (!_referenceGraph.isEmpty()) {
+    while (!_referenceGraph.isEmpty) {
       VariableElement element = _referenceGraph.removeSink();
       while (element != null) {
         computeValueFor(element);
         element = _referenceGraph.removeSink();
       }
-      if (!_referenceGraph.isEmpty()) {
+      if (!_referenceGraph.isEmpty) {
         List<VariableElement> variablesInCycle = _referenceGraph.findCycle();
         if (variablesInCycle == null) {
           AnalysisEngine.instance.logger.logError("Exiting constant value computer with ${_referenceGraph.nodeCount} variables that are neither sinks no in a cycle");
@@ -256,29 +256,29 @@
   }
 }
 /**
- * Instances of the class {@code ConstantVisitor} evaluate constant expressions to produce their
+ * Instances of the class `ConstantVisitor` 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>
+ *
+ * * A literal number.
+ * * A literal boolean.
+ * * A literal string where any interpolated expression is a compile-time constant that evaluates
+ * to a numeric, string or boolean value or to `null`.
+ * * `null`.
+ * * A reference to a static constant variable.
+ * * An identifier expression that denotes a constant variable, a class or a type variable.
+ * * A constant constructor invocation.
+ * * A constant list literal.
+ * * A constant map literal.
+ * * A simple or qualified identifier denoting a top-level function or a static method.
+ * * A parenthesized expression `(e)` where `e` is a constant expression.
+ * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`,`e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a
+ * numeric, string or boolean value or to `null`.
+ * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where`e`, `e1` and `e2` are constant expressions that evaluate to a boolean value or
+ * to `null`.
+ * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,`e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2`are constant expressions that evaluate to an integer value or to `null`.
+ * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`,`e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`,`e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2`are constant expressions that evaluate to a numeric value or to `null`.
+ *
  * </blockquote>
  */
 class ConstantVisitor extends GeneralizingASTVisitor<EvaluationResultImpl> {
@@ -298,7 +298,7 @@
     EvaluationResultImpl rightResult = node.rightOperand.accept(this);
     TokenType operatorType = node.operator.type;
     if (operatorType != TokenType.BANG_EQ && operatorType != TokenType.EQ_EQ) {
-      if (leftResult is ValidResult && ((leftResult as ValidResult)).isNull() || rightResult is ValidResult && ((rightResult as ValidResult)).isNull()) {
+      if (leftResult is ValidResult && ((leftResult as ValidResult)).isNull || rightResult is ValidResult && ((rightResult as ValidResult)).isNull) {
         return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
       }
     }
@@ -350,7 +350,7 @@
   EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => new ValidResult(node.value);
   EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpression node) {
     ConstructorElement constructor = node.element;
-    if (constructor != null && constructor.isConst()) {
+    if (constructor != null && constructor.isConst) {
       node.argumentList.accept(this);
       return ValidResult.RESULT_OBJECT;
     }
@@ -399,7 +399,7 @@
           Element enclosingElement = function.enclosingElement;
           if (enclosingElement is CompilationUnitElement) {
             LibraryElement library = ((enclosingElement as CompilationUnitElement)).library;
-            if (library.isDartCore()) {
+            if (library.isDartCore) {
               EvaluationResultImpl leftArgument = arguments[0].accept(this);
               EvaluationResultImpl rightArgument = arguments[1].accept(this);
               return leftArgument.equalEqual(node, rightArgument);
@@ -416,7 +416,7 @@
   EvaluationResultImpl visitPrefixedIdentifier(PrefixedIdentifier node) => getConstantValue(node, node.element);
   EvaluationResultImpl visitPrefixExpression(PrefixExpression node) {
     EvaluationResultImpl operand = node.operand.accept(this);
-    if (operand is ValidResult && ((operand as ValidResult)).isNull()) {
+    if (operand is ValidResult && ((operand as ValidResult)).isNull) {
       return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
     }
     while (true) {
@@ -479,7 +479,7 @@
 
   /**
    * Return the union of the errors encoded in the given results.
-   * @param leftResult the first set of errors, or {@code null} if there was no previous collection
+   * @param leftResult the first set of errors, or `null` if there was no previous collection
    * of errors
    * @param rightResult the errors to be added to the collection, or a valid result if there are no
    * errors to be added
@@ -497,7 +497,7 @@
   }
 }
 /**
- * Instances of the class {@code DirectedGraph} implement a directed graph in which the nodes are
+ * Instances of the class `DirectedGraph` implement a directed graph in which the nodes are
  * arbitrary (client provided) objects and edges are represented implicitly. The graph will allow an
  * edge from any node to any other node, including itself, but will not represent multiple edges
  * between the same pair of nodes.
@@ -543,7 +543,7 @@
   }
 
   /**
-   * Return a list of nodes that form a cycle, or {@code null} if there are no cycles in this graph.
+   * Return a list of nodes that form a cycle, or `null` if there are no cycles in this graph.
    * @return a list of nodes that form a cycle
    */
   List<N> findCycle() => null;
@@ -570,10 +570,10 @@
   }
 
   /**
-   * Return {@code true} if this graph is empty.
-   * @return {@code true} if this graph is empty
+   * Return `true` if this graph is empty.
+   * @return `true` if this graph is empty
    */
-  bool isEmpty() => _edges.isEmpty;
+  bool get isEmpty => _edges.isEmpty;
 
   /**
    * Remove all of the given nodes from this graph. As a consequence, any edges for which those
@@ -592,7 +592,7 @@
    * the same (neither node will either be added or removed).
    * @param head the node at the head of the edge
    * @param tail the node at the tail of the edge
-   * @return {@code true} if the graph was modified as a result of this operation
+   * @return `true` if the graph was modified as a result of this operation
    */
   void removeEdge(N head, N tail) {
     Set<N> tails = _edges[head];
@@ -616,7 +616,7 @@
   /**
    * Find one node (referred to as a sink node) that has no outgoing edges (that is, for which there
    * are no edges that have that node as the head of the edge) and remove it from this graph. Return
-   * the node that was removed, or {@code null} if there are no such nodes either because the graph
+   * the node that was removed, or `null` if there are no such nodes either because the graph
    * is empty or because every node in the graph has at least one outgoing edge. As a consequence of
    * removing the node from the graph any edges for which that node was a tail will also be removed.
    * @return the sink node that was removed
@@ -632,7 +632,7 @@
 
   /**
    * Return one node that has no outgoing edges (that is, for which there are no edges that have
-   * that node as the head of the edge), or {@code null} if there are no such nodes.
+   * that node as the head of the edge), or `null` if there are no such nodes.
    * @return a sink node
    */
   N findSink() {
@@ -643,7 +643,7 @@
   }
 }
 /**
- * Instances of the class {@code ErrorResult} represent the result of evaluating an expression that
+ * Instances of the class `ErrorResult` represent the result of evaluating an expression that
  * is not a valid compile time constant.
  */
 class ErrorResult extends EvaluationResultImpl {
@@ -687,6 +687,7 @@
   EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateError(node, this);
   EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideError(node, this);
   EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualError(node, this);
+  bool equalValues(EvaluationResultImpl result) => false;
   List<ErrorResult_ErrorData> get errorData => _errors;
   EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanError(node, this);
   EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this);
@@ -781,7 +782,7 @@
   ASTNode get node => _node;
 }
 /**
- * Instances of the class {@code InternalResult} represent the result of attempting to evaluate a
+ * Instances of the class `InternalResult` represent the result of attempting to evaluate a
  * expression.
  */
 abstract class EvaluationResultImpl {
@@ -793,6 +794,7 @@
   EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand);
   EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand);
   EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand);
+  bool equalValues(EvaluationResultImpl result);
   EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand);
   EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
   EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand);
@@ -851,7 +853,7 @@
   EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand);
 }
 /**
- * Instances of the class {@code ReferenceFinder} add reference information for a given variable to
+ * Instances of the class `ReferenceFinder` add reference information for a given variable to
  * the bi-directional mapping used to order the evaluation of constants.
  */
 class ReferenceFinder extends RecursiveASTVisitor<Object> {
@@ -885,7 +887,7 @@
     }
     if (element is VariableElement) {
       VariableElement variable = element as VariableElement;
-      if (variable.isConst()) {
+      if (variable.isConst) {
         _referenceGraph.addEdge(_source, variable);
       }
     }
@@ -893,7 +895,7 @@
   }
 }
 /**
- * Instances of the class {@code ValidResult} represent the result of attempting to evaluate a valid
+ * Instances of the class `ValidResult` represent the result of attempting to evaluate a valid
  * compile time constant expression.
  */
 class ValidResult extends EvaluationResultImpl {
@@ -916,7 +918,7 @@
   static ValidResult RESULT_INT = new ValidResult(null);
 
   /**
-   * A result object representing the {@code null} value.
+   * A result object representing the `null` value.
    */
   static ValidResult RESULT_NULL = new ValidResult(null);
 
@@ -964,7 +966,7 @@
   EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToValid(node, this);
   EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndValid(node, this);
   EvaluationResultImpl bitNot(Expression node) {
-    if (isSomeInt()) {
+    if (isSomeInt) {
       return RESULT_INT;
     }
     if (_value == null) {
@@ -979,6 +981,7 @@
   EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateValid(node, this);
   EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideValid(node, this);
   EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualValid(node, this);
+  bool equalValues(EvaluationResultImpl result) => identical(equalEqual(null, result), RESULT_TRUE);
   Object get value => _value;
   EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanValid(node, this);
   EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualValid(node, this);
@@ -987,7 +990,7 @@
   EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualValid(node, this);
   EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndValid(node, this);
   EvaluationResultImpl logicalNot(Expression node) {
-    if (isSomeBool()) {
+    if (isSomeBool) {
       return RESULT_BOOL;
     }
     if (_value == null) {
@@ -1000,7 +1003,7 @@
   EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrValid(node, this);
   EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusValid(node, this);
   EvaluationResultImpl negated(Expression node) {
-    if (isSomeNum()) {
+    if (isSomeNum) {
       return RESULT_INT;
     }
     if (_value == null) {
@@ -1039,8 +1042,8 @@
   }
   EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeNum() || leftOperand2.isSomeNum()) {
-      if (isAnyNum() && leftOperand2.isAnyNum()) {
+    if (isSomeNum || leftOperand2.isSomeNum) {
+      if (isAnyNum && leftOperand2.isAnyNum) {
         return RESULT_NUM;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
@@ -1071,8 +1074,8 @@
   }
   EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeInt() || leftOperand2.isSomeInt()) {
-      if (isAnyInt() && leftOperand2.isAnyInt()) {
+    if (isSomeInt || leftOperand2.isSomeInt) {
+      if (isAnyInt && leftOperand2.isAnyInt) {
         return RESULT_INT;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
@@ -1095,8 +1098,8 @@
   }
   EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeInt() || leftOperand2.isSomeInt()) {
-      if (isAnyInt() && leftOperand2.isAnyInt()) {
+    if (isSomeInt || leftOperand2.isSomeInt) {
+      if (isAnyInt && leftOperand2.isAnyInt) {
         return RESULT_INT;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
@@ -1119,8 +1122,8 @@
   }
   EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeInt() || leftOperand2.isSomeInt()) {
-      if (isAnyInt() && leftOperand2.isAnyInt()) {
+    if (isSomeInt || leftOperand2.isSomeInt) {
+      if (isAnyInt && leftOperand2.isAnyInt) {
         return RESULT_INT;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
@@ -1151,8 +1154,8 @@
   }
   EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeNum() || leftOperand2.isSomeNum()) {
-      if (isAnyNum() && leftOperand2.isAnyNum()) {
+    if (isSomeNum || leftOperand2.isSomeNum) {
+      if (isAnyNum && leftOperand2.isAnyNum) {
         return RESULT_NUM;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
@@ -1183,7 +1186,7 @@
   EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand) {
     if (node is BinaryExpression) {
-      if (!isAnyNullBoolNumString() || !leftOperand.isAnyNullBoolNumString()) {
+      if (!isAnyNullBoolNumString || !leftOperand.isAnyNullBoolNumString) {
         return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
       }
     }
@@ -1220,8 +1223,8 @@
   EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeNum() || leftOperand2.isSomeNum()) {
-      if (isAnyNum() && leftOperand2.isAnyNum()) {
+    if (isSomeNum || leftOperand2.isSomeNum) {
+      if (isAnyNum && leftOperand2.isAnyNum) {
         return RESULT_BOOL;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
@@ -1247,8 +1250,8 @@
     return error(node);
   }
   EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeNum() || leftOperand2.isSomeNum()) {
-      if (isAnyNum() && leftOperand2.isAnyNum()) {
+    if (isSomeNum || leftOperand2.isSomeNum) {
+      if (isAnyNum && leftOperand2.isAnyNum) {
         return RESULT_BOOL;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
@@ -1275,8 +1278,8 @@
   }
   EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeNum() || leftOperand2.isSomeNum()) {
-      if (isAnyNum() && leftOperand2.isAnyNum()) {
+    if (isSomeNum || leftOperand2.isSomeNum) {
+      if (isAnyNum && leftOperand2.isAnyNum) {
         return RESULT_INT;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
@@ -1310,8 +1313,8 @@
   EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeNum() || leftOperand2.isSomeNum()) {
-      if (isAnyNum() && leftOperand2.isAnyNum()) {
+    if (isSomeNum || leftOperand2.isSomeNum) {
+      if (isAnyNum && leftOperand2.isAnyNum) {
         return RESULT_BOOL;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
@@ -1337,8 +1340,8 @@
     return error(node);
   }
   EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeNum() || leftOperand2.isSomeNum()) {
-      if (isAnyNum() && leftOperand2.isAnyNum()) {
+    if (isSomeNum || leftOperand2.isSomeNum) {
+      if (isAnyNum && leftOperand2.isAnyNum) {
         return RESULT_BOOL;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
@@ -1365,8 +1368,8 @@
   }
   EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOperand) {
-    if (isSomeBool() || leftOperand.isSomeBool()) {
-      if (isAnyBool() && leftOperand.isAnyBool()) {
+    if (isSomeBool || leftOperand.isSomeBool) {
+      if (isAnyBool && leftOperand.isAnyBool) {
         return RESULT_BOOL;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
@@ -1382,8 +1385,8 @@
   }
   EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOperand) {
-    if (isSomeBool() || leftOperand.isSomeBool()) {
-      if (isAnyBool() && leftOperand.isAnyBool()) {
+    if (isSomeBool || leftOperand.isSomeBool) {
+      if (isAnyBool && leftOperand.isAnyBool) {
         return RESULT_BOOL;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
@@ -1396,8 +1399,8 @@
   }
   EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeNum() || leftOperand2.isSomeNum()) {
-      if (isAnyNum() && leftOperand2.isAnyNum()) {
+    if (isSomeNum || leftOperand2.isSomeNum) {
+      if (isAnyNum && leftOperand2.isAnyNum) {
         return RESULT_NUM;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
@@ -1424,7 +1427,7 @@
   }
   EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyNullBoolNumString() || !leftOperand.isAnyNullBoolNumString()) {
+    if (!isAnyNullBoolNumString || !leftOperand.isAnyNullBoolNumString) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
     }
     Object leftValue = leftOperand.value;
@@ -1459,8 +1462,8 @@
   }
   EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeNum() || leftOperand2.isSomeNum()) {
-      if (isAnyNum() && leftOperand2.isAnyNum()) {
+    if (isSomeNum || leftOperand2.isSomeNum) {
+      if (isAnyNum && leftOperand2.isAnyNum) {
         return RESULT_NUM;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
@@ -1490,8 +1493,8 @@
   }
   EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeInt() || leftOperand2.isSomeInt()) {
-      if (isAnyInt() && leftOperand2.isAnyInt()) {
+    if (isSomeInt || leftOperand2.isSomeInt) {
+      if (isAnyInt && leftOperand2.isAnyInt) {
         return RESULT_INT;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
@@ -1514,8 +1517,8 @@
   }
   EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeInt() || leftOperand2.isSomeInt()) {
-      if (isAnyInt() && leftOperand2.isAnyInt()) {
+    if (isSomeInt || leftOperand2.isSomeInt) {
+      if (isAnyInt && leftOperand2.isAnyInt) {
         return RESULT_INT;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
@@ -1538,8 +1541,8 @@
   }
   EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (isSomeNum() || leftOperand2.isSomeNum()) {
-      if (isAnyNum() && leftOperand2.isAnyNum()) {
+    if (isSomeNum || leftOperand2.isSomeNum) {
+      if (isAnyNum && leftOperand2.isAnyNum) {
         return RESULT_NUM;
       }
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
@@ -1564,7 +1567,7 @@
     }
     return error(node);
   }
-  bool isNull() => identical(this, RESULT_NULL);
+  bool get isNull => identical(this, RESULT_NULL);
 
   /**
    * Return the result of applying boolean conversion to the given value.
@@ -1595,37 +1598,37 @@
   /**
    * Checks if this result has type "bool", with known or unknown value.
    */
-  bool isAnyBool() => isSomeBool() || identical(this, RESULT_TRUE) || identical(this, RESULT_FALSE);
+  bool get isAnyBool => isSomeBool || identical(this, RESULT_TRUE) || identical(this, RESULT_FALSE);
 
   /**
    * Checks if this result has type "int", with known or unknown value.
    */
-  bool isAnyInt() => identical(this, RESULT_INT) || _value is int;
+  bool get isAnyInt => identical(this, RESULT_INT) || _value is int;
 
   /**
-   * Checks if this result has one of the types - "bool", "num" or "string"; or may be {@code null}.
+   * Checks if this result has one of the types - "bool", "num" or "string"; or may be `null`.
    */
-  bool isAnyNullBoolNumString() => isNull() || isAnyBool() || isAnyNum() || _value is String;
+  bool get isAnyNullBoolNumString => isNull || isAnyBool || isAnyNum || _value is String;
 
   /**
    * Checks if this result has type "num", with known or unknown value.
    */
-  bool isAnyNum() => isSomeNum() || _value is num;
+  bool get isAnyNum => isSomeNum || _value is num;
 
   /**
    * Checks if this result has type "bool", exact value of which we don't know.
    */
-  bool isSomeBool() => identical(this, RESULT_BOOL);
+  bool get isSomeBool => identical(this, RESULT_BOOL);
 
   /**
    * Checks if this result has type "int", exact value of which we don't know.
    */
-  bool isSomeInt() => identical(this, RESULT_INT);
+  bool get isSomeInt => identical(this, RESULT_INT);
 
   /**
    * Checks if this result has type "num" (or "int"), exact value of which we don't know.
    */
-  bool isSomeNum() => identical(this, RESULT_DYNAMIC) || identical(this, RESULT_INT) || identical(this, RESULT_NUM);
+  bool get isSomeNum => identical(this, RESULT_DYNAMIC) || identical(this, RESULT_INT) || identical(this, RESULT_NUM);
   double toDouble(int value) => value.toDouble();
 
   /**
diff --git a/pkg/analyzer_experimental/lib/src/generated/element.dart b/pkg/analyzer_experimental/lib/src/generated/element.dart
index 5cc4a23..af56601 100644
--- a/pkg/analyzer_experimental/lib/src/generated/element.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/element.dart
@@ -13,7 +13,7 @@
 import 'constant.dart' show EvaluationResultImpl;
 import 'utilities_dart.dart';
 /**
- * The interface {@code ClassElement} defines the behavior of elements that represent a class.
+ * The interface `ClassElement` defines the behavior of elements that represent a class.
  * @coverage dart.engine.element
  */
 abstract class ClassElement implements Element {
@@ -45,7 +45,7 @@
 
   /**
    * Return the element representing the getter with the given name that is declared in this class,
-   * or {@code null} if this class does not declare a getter with the given name.
+   * or `null` if this class does not declare a getter with the given name.
    * @param getterName the name of the getter to be returned
    * @return the getter declared in this class with the given name
    */
@@ -53,7 +53,7 @@
 
   /**
    * Return an array containing all of the interfaces that are implemented by this class.
-   * <p>
+   *
    * <b>Note:</b> Because the element model represents the state of the code, it is possible for it
    * to be semantically invalid. In particular, it is not safe to assume that the inheritance
    * structure of a class does not contain a cycle. Clients that traverse the inheritance structure
@@ -64,7 +64,7 @@
 
   /**
    * Return the element representing the method with the given name that is declared in this class,
-   * or {@code null} if this class does not declare a method with the given name.
+   * or `null` if this class does not declare a method with the given name.
    * @param methodName the name of the method to be returned
    * @return the method declared in this class with the given name
    */
@@ -79,7 +79,7 @@
   /**
    * 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.
-   * <p>
+   *
    * <b>Note:</b> Because the element model represents the state of the code, it is possible for it
    * to be semantically invalid. In particular, it is not safe to assume that the inheritance
    * structure of a class does not contain a cycle. Clients that traverse the inheritance structure
@@ -89,7 +89,7 @@
   List<InterfaceType> get mixins;
 
   /**
-   * Return the named constructor declared in this class with the given name, or {@code null} if
+   * Return the named constructor declared in this class with the given name, or `null` if
    * this class does not declare a named constructor with the given name.
    * @param name the name of the constructor to be returned
    * @return the element representing the specified constructor
@@ -98,17 +98,17 @@
 
   /**
    * Return the element representing the setter with the given name that is declared in this class,
-   * or {@code null} if this class does not declare a setter with the given name.
+   * or `null` if this class does not declare a setter with the given name.
    * @param setterName the name of the getter to be returned
    * @return the setter declared in this class with the given name
    */
   PropertyAccessorElement getSetter(String setterName);
 
   /**
-   * 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
+   * Return the superclass of this class, or `null` if the class represents the class
+   * 'Object'. All other classes will have a non-`null` superclass. If the superclass was not
    * explicitly declared then the implicit superclass 'Object' will be returned.
-   * <p>
+   *
    * <b>Note:</b> Because the element model represents the state of the code, it is possible for it
    * to be semantically invalid. In particular, it is not safe to assume that the inheritance
    * structure of a class does not contain a cycle. Clients that traverse the inheritance structure
@@ -130,7 +130,7 @@
   List<TypeVariableElement> get typeVariables;
 
   /**
-   * Return the unnamed constructor declared in this class, or {@code null} if this class does not
+   * Return the unnamed constructor declared in this class, or `null` if this class does not
    * declare an unnamed constructor but does declare named constructors. The returned constructor
    * will be synthetic if this class does not declare any constructors, in which case it will
    * represent the default constructor for the class.
@@ -139,55 +139,61 @@
   ConstructorElement get unnamedConstructor;
 
   /**
-   * Return {@code true} if this class or its superclass declares a non-final instance field.
-   * @return {@code true} if this class or its superclass declares a non-final instance field
+   * Return `true` if this class has (implicit or explicit) default constructor.
+   * @return `true` if this class has (implicit or explicit) default constructor
+   */
+  bool hasDefaultConstructor();
+
+  /**
+   * Return `true` if this class or its superclass declares a non-final instance field.
+   * @return `true` if this class or its superclass declares a non-final instance field
    */
   bool hasNonFinalField();
 
   /**
-   * Return {@code true} if this class has reference to super (so, for example, cannot be used as a
+   * Return `true` if this class has reference to super (so, for example, cannot be used as a
    * mixin).
-   * @return {@code true} if this class has reference to super
+   * @return `true` if this class has reference to super
    */
   bool hasReferenceToSuper();
 
   /**
-   * 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
+   * Return `true` if this class is abstract. A class is abstract if it has an explicit`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
+   * @return `true` if this class is abstract
    */
-  bool isAbstract();
+  bool get isAbstract;
 
   /**
-   * Return {@code true} if this class is defined by a typedef construct.
-   * @return {@code true} if this class is defined by a typedef construct
+   * Return `true` if this class is defined by a typedef construct.
+   * @return `true` if this class is defined by a typedef construct
    */
-  bool isTypedef();
+  bool get isTypedef;
 
   /**
-   * Return {@code true} if this class can validly be used as a mixin when defining another class.
+   * Return `true` if this class can validly be used as a mixin when defining another class.
    * The behavior of this method is defined by the Dart Language Specification in section 9:
    * <blockquote>It is a compile-time error if a declared or derived mixin refers to super. It is a
    * compile-time error if a declared or derived mixin explicitly declares a constructor. It is a
    * compile-time error if a mixin is derived from a class whose superclass is not
    * Object.</blockquote>
-   * @return {@code true} if this class can validly be used as a mixin
+   * @return `true` if this class can validly be used as a mixin
    */
-  bool isValidMixin();
+  bool get isValidMixin;
 
   /**
    * Return the element representing the getter that results from looking up the given getter in
-   * this class with respect to the given library, or {@code null} if the look up fails. The
+   * this class with respect to the given library, or `null` if the look up fails. The
    * behavior of this method is defined by the Dart Language Specification in section 12.15.1:
    * <blockquote>The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
    * with respect to library <i>L</i> is:
-   * <ul>
-   * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
+   *
+   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
    * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
    * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
    * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.</li>
-   * </ul>
+   * Otherwise, we say that the lookup has failed.
+   *
    * </blockquote>
    * @param getterName the name of the getter being looked up
    * @param library the library with respect to which the lookup is being performed
@@ -198,16 +204,16 @@
 
   /**
    * Return the element representing the method that results from looking up the given method in
-   * this class with respect to the given library, or {@code null} if the look up fails. The
+   * this class with respect to the given library, or `null` if the look up fails. The
    * behavior of this method is defined by the Dart Language Specification in section 12.15.1:
    * <blockquote> The result of looking up method <i>m</i> in class <i>C</i> with respect to library
    * <i>L</i> is:
-   * <ul>
-   * <li>If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
+   *
+   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
    * that method is the result of the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then
    * the result of the lookup is the result of looking up method <i>m</i> in <i>S</i> with respect
-   * to <i>L</i>. Otherwise, we say that the lookup has failed.</li>
-   * </ul>
+   * to <i>L</i>. Otherwise, we say that the lookup has failed.
+   *
    * </blockquote>
    * @param methodName the name of the method being looked up
    * @param library the library with respect to which the lookup is being performed
@@ -218,17 +224,17 @@
 
   /**
    * Return the element representing the setter that results from looking up the given setter in
-   * this class with respect to the given library, or {@code null} if the look up fails. The
+   * this class with respect to the given library, or `null` if the look up fails. The
    * behavior of this method is defined by the Dart Language Specification in section 12.16:
    * <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
    * with respect to library <i>L</i> is:
-   * <ul>
-   * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
+   *
+   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
    * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
    * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
    * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.</li>
-   * </ul>
+   * Otherwise, we say that the lookup has failed.
+   *
    * </blockquote>
    * @param setterName the name of the setter being looked up
    * @param library the library with respect to which the lookup is being performed
@@ -238,8 +244,8 @@
   PropertyAccessorElement lookUpSetter(String setterName, LibraryElement library);
 }
 /**
- * The interface {@code ClassMemberElement} defines the behavior of elements that are contained
- * within a {@link ClassElement}.
+ * The interface `ClassMemberElement` defines the behavior of elements that are contained
+ * within a [ClassElement].
  */
 abstract class ClassMemberElement implements Element {
 
@@ -250,7 +256,7 @@
   ClassElement get enclosingElement;
 }
 /**
- * The interface {@code CompilationUnitElement} defines the behavior of elements representing a
+ * The interface `CompilationUnitElement` defines the behavior of elements representing a
  * compilation unit.
  * @coverage dart.engine.element
  */
@@ -288,7 +294,7 @@
   List<TopLevelVariableElement> get topLevelVariables;
 
   /**
-   * Return the class defined in this compilation unit that has the given name, or {@code null} if
+   * Return the class defined in this compilation unit that has the given name, or `null` if
    * this compilation unit does not define a class with the given name.
    * @param className the name of the class to be returned
    * @return the class with the given name that is defined in this compilation unit
@@ -302,7 +308,7 @@
   List<ClassElement> get types;
 }
 /**
- * The interface {@code ConstructorElement} defines the behavior of elements representing a
+ * The interface `ConstructorElement` defines the behavior of elements representing a
  * constructor or a factory method defined within a type.
  * @coverage dart.engine.element
  */
@@ -315,33 +321,40 @@
   ConstructorElement get redirectedConstructor;
 
   /**
-   * Return {@code true} if this constructor is a const constructor.
-   * @return {@code true} if this constructor is a const constructor
+   * Return `true` if this constructor is a const constructor.
+   * @return `true` if this constructor is a const constructor
    */
-  bool isConst();
+  bool get isConst;
 
   /**
-   * Return {@code true} if this constructor represents a factory constructor.
-   * @return {@code true} if this constructor represents a factory constructor
+   * Return `true` if this constructor can be used as a default constructor - unnamed and has
+   * no required parameters.
+   * @return `true` if this constructor can be used as a default constructor.
    */
-  bool isFactory();
+  bool get isDefaultConstructor;
+
+  /**
+   * Return `true` if this constructor represents a factory constructor.
+   * @return `true` if this constructor represents a factory constructor
+   */
+  bool get isFactory;
 }
 /**
- * The interface {@code Element} defines the behavior common to all of the elements in the element
+ * The interface `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>
+ *
+ * * default constructors in classes that do not define any explicit constructors,
+ * * getters and setters that are induced by explicit field declarations,
+ * * fields that are induced by explicit declarations of getters and setters, and
+ * * functions representing the initialization expression for a variable.
+ *
+ *
  * 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.
@@ -364,7 +377,7 @@
 
   /**
    * Return the documentation comment for this element as it appears in the original source
-   * (complete with the beginning and ending delimiters), or {@code null} if this element does not
+   * (complete with the beginning and ending delimiters), or `null` if this element does not
    * have a documentation comment associated with it. This can be a long-running operation if the
    * information needed to access the comment is not cached.
    * @return this element's documentation comment
@@ -374,7 +387,7 @@
   String computeDocumentationComment();
 
   /**
-   * 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.
+   * Return the element of the given class that most immediately encloses this element, or`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
    */
@@ -387,16 +400,16 @@
   AnalysisContext get context;
 
   /**
-   * Return the display name of this element, or {@code null} if this element does not have a name.
-   * <p>
+   * Return the display name of this element, or `null` if this element does not have a name.
+   *
    * In most cases the name and the display name are the same. Differences though are cases such as
-   * setters where the name of some setter {@code set f(x)} is {@code f=}, instead of {@code f}.
+   * setters where the name of some setter `set f(x)` is `f=`, instead of `f`.
    * @return the display name of this element
    */
   String get displayName;
 
   /**
-   * 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
+   * Return the element that either physically or logically encloses this element. This will be`null` if this element is a library because libraries are the top-level elements in the
    * model.
    * @return the element that encloses this element
    */
@@ -410,7 +423,7 @@
 
   /**
    * Return the library that contains this element. This will be the element itself if it is a
-   * library element. This will be {@code null} if this element is an HTML file because HTML files
+   * library element. This will be `null` if this element is an HTML file because HTML files
    * are not contained in libraries.
    * @return the library that contains this element
    */
@@ -430,43 +443,43 @@
   List<ElementAnnotation> 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, or `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
+   * element, or `-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 the source that contains this element, or {@code null} if this element is not contained
+   * Return the source that contains this element, or `null` if this element is not contained
    * in a source.
    * @return the source that contains this element
    */
   Source get source;
 
   /**
-   * Return {@code true} if this element, assuming that it is within scope, is accessible to code in
+   * Return `true` if this element, assuming that it is within scope, is accessible to code in
    * the given library. This is defined by the Dart Language Specification in section 3.2:
    * <blockquote> A declaration <i>m</i> is accessible to library <i>L</i> if <i>m</i> is declared
    * in <i>L</i> or if <i>m</i> is public. </blockquote>
    * @param library the library in which a possible reference to this element would occur
-   * @return {@code true} if this element is accessible to code in the given library
+   * @return `true` if this element is accessible to code in the given library
    */
   bool isAccessibleIn(LibraryElement library);
 
   /**
-   * Return {@code true} if this element is synthetic. A synthetic element is an element that is not
+   * Return `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
+   * @return `true` if this element is synthetic
    */
-  bool isSynthetic();
+  bool get isSynthetic;
 
   /**
    * Use the given visitor to visit all of the children of this element. There is no guarantee of
@@ -476,7 +489,7 @@
   void visitChildren(ElementVisitor<Object> visitor);
 }
 /**
- * The interface {@code ElementAnnotation} defines the behavior of objects representing a single
+ * The interface `ElementAnnotation` defines the behavior of objects representing a single
  * annotation associated with an element.
  * @coverage dart.engine.element
  */
@@ -490,7 +503,7 @@
   Element get element;
 }
 /**
- * The enumeration {@code ElementKind} defines the various kinds of elements in the element model.
+ * The enumeration `ElementKind` defines the various kinds of elements in the element model.
  * @coverage dart.engine.element
  */
 class ElementKind implements Comparable<ElementKind> {
@@ -528,7 +541,7 @@
   final int ordinal;
 
   /**
-   * Return the kind of the given element, or {@link #ERROR} if the element is {@code null}. This is
+   * Return the kind of the given element, or [ERROR] if the element is `null`. This is
    * a utility method that can reduce the need for null checks in other places.
    * @param element the element whose kind is to be returned
    * @return the kind of the given element
@@ -555,7 +568,7 @@
 
   /**
    * Return the name displayed in the UI for this kind of element.
-   * @return the name of this {@link ElementKind} to display in UI.
+   * @return the name of this [ElementKind] to display in UI.
    */
   String get displayName => _displayName;
   int compareTo(ElementKind other) => ordinal - other.ordinal;
@@ -563,7 +576,7 @@
   String toString() => name;
 }
 /**
- * The interface {@code ElementLocation} defines the behavior of objects that represent the location
+ * The interface `ElementLocation` defines the behavior of objects that represent the location
  * of an element within the element model.
  * @coverage dart.engine.element
  */
@@ -577,7 +590,7 @@
   String get encoding;
 }
 /**
- * The interface {@code ElementVisitor} defines the behavior of objects that can be used to visit an
+ * The interface `ElementVisitor` defines the behavior of objects that can be used to visit an
  * element structure.
  * @coverage dart.engine.element
  */
@@ -606,7 +619,7 @@
   R visitTypeVariableElement(TypeVariableElement element);
 }
 /**
- * The interface {@code EmbeddedHtmlScriptElement} defines the behavior of elements representing a
+ * The interface `EmbeddedHtmlScriptElement` defines the behavior of elements representing a
  * script tag in an HTML file having content that defines a Dart library.
  * @coverage dart.engine.element
  */
@@ -614,12 +627,12 @@
 
   /**
    * Return the library element defined by the content of the script tag.
-   * @return the library element (not {@code null})
+   * @return the library element (not `null`)
    */
   LibraryElement get scriptLibrary;
 }
 /**
- * The interface {@code ExecutableElement} defines the behavior of elements representing an
+ * The interface `ExecutableElement` defines the behavior of elements representing an
  * executable object, including functions, methods, constructors, getters, and setters.
  * @coverage dart.engine.element
  */
@@ -650,28 +663,34 @@
   List<ParameterElement> get parameters;
 
   /**
+   * Return the return type defined by this executable element.
+   * @return the return type defined by this executable element
+   */
+  Type2 get returnType;
+
+  /**
    * Return the type of function defined by this executable element.
    * @return the type of function defined by this executable element
    */
   FunctionType get type;
 
   /**
-   * Return {@code true} if this executable element is an operator. The test may be based on the
+   * Return `true` if this executable element is an operator. The test may be based on the
    * name of the executable element, in which case the result will be correct when the name is
    * legal.
-   * @return {@code true} if this executable element is an operator
+   * @return `true` if this executable element is an operator
    */
-  bool isOperator();
+  bool get isOperator;
 
   /**
-   * Return {@code true} if this element is a static element. A static element is an element that is
+   * Return `true` if this element is a static element. A static element is an element that is
    * not associated with a particular instance, but rather with an entire library or class.
-   * @return {@code true} if this executable element is a static element
+   * @return `true` if this executable element is a static element
    */
-  bool isStatic();
+  bool get isStatic;
 }
 /**
- * The interface {@code ExportElement} defines the behavior of objects representing information
+ * The interface `ExportElement` defines the behavior of objects representing information
  * about a single export directive within a library.
  * @coverage dart.engine.element
  */
@@ -696,49 +715,49 @@
   LibraryElement get exportedLibrary;
 }
 /**
- * The interface {@code ExternalHtmlScriptElement} defines the behavior of elements representing a
- * script tag in an HTML file having a {@code source} attribute that references a Dart library
+ * The interface `ExternalHtmlScriptElement` defines the behavior of elements representing a
+ * script tag in an HTML file having a `source` attribute that references a Dart library
  * source file.
  * @coverage dart.engine.element
  */
 abstract class ExternalHtmlScriptElement implements HtmlScriptElement {
 
   /**
-   * Return the source referenced by this element, or {@code null} if this element does not
+   * Return the source referenced by this element, or `null` if this element does not
    * reference a Dart library source file.
    * @return the source for the external Dart library
    */
   Source get scriptSource;
 }
 /**
- * The interface {@code FieldElement} defines the behavior of elements representing a field defined
+ * The interface `FieldElement` defines the behavior of elements representing a field defined
  * within a type.
  * @coverage dart.engine.element
  */
 abstract class FieldElement implements ClassMemberElement, PropertyInducingElement {
 }
 /**
- * The interface {@code FieldFormalParameterElement} defines the behavior of elements representing a
+ * The interface `FieldFormalParameterElement` defines the behavior of elements representing a
  * field formal parameter defined within a constructor element.
  */
 abstract class FieldFormalParameterElement implements ParameterElement {
 
   /**
-   * Return the field element associated with this field formal parameter, or {@code null} if the
+   * Return the field element associated with this field formal parameter, or `null` if the
    * parameter references a field that doesn't exist.
    * @return the field element associated with this field formal parameter
    */
   FieldElement get field;
 }
 /**
- * The interface {@code FunctionElement} defines the behavior of elements representing a function.
+ * The interface `FunctionElement` defines the behavior of elements representing a function.
  * @coverage dart.engine.element
  */
 abstract class FunctionElement implements ExecutableElement, LocalElement {
 }
 /**
- * The interface {@code FunctionTypeAliasElement} defines the behavior of elements representing a
- * function type alias ({@code typedef}).
+ * The interface `FunctionTypeAliasElement` defines the behavior of elements representing a
+ * function type alias (`typedef`).
  * @coverage dart.engine.element
  */
 abstract class FunctionTypeAliasElement implements Element {
@@ -756,6 +775,12 @@
   List<ParameterElement> get parameters;
 
   /**
+   * Return the return type defined by this type alias.
+   * @return the return type defined by this type alias
+   */
+  Type2 get returnType;
+
+  /**
    * Return the type of function defined by this type alias.
    * @return the type of function defined by this type alias
    */
@@ -768,7 +793,7 @@
   List<TypeVariableElement> get typeVariables;
 }
 /**
- * The interface {@code HideElementCombinator} defines the behavior of combinators that cause some
+ * The interface `HideElementCombinator` defines the behavior of combinators that cause some
  * of the names in a namespace to be hidden when being imported.
  * @coverage dart.engine.element
  */
@@ -782,7 +807,7 @@
   List<String> get hiddenNames;
 }
 /**
- * The interface {@code HtmlElement} defines the behavior of elements representing an HTML file.
+ * The interface `HtmlElement` defines the behavior of elements representing an HTML file.
  * @coverage dart.engine.element
  */
 abstract class HtmlElement implements Element {
@@ -791,12 +816,12 @@
    * Return an array containing all of the script elements contained in the HTML file. This includes
    * scripts with libraries that are defined by the content of a script tag as well as libraries
    * that are referenced in the {@core source} attribute of a script tag.
-   * @return the script elements in the HTML file (not {@code null}, contains no {@code null}s)
+   * @return the script elements in the HTML file (not `null`, contains no `null`s)
    */
   List<HtmlScriptElement> get scripts;
 }
 /**
- * The interface {@code HtmlScriptElement} defines the behavior of elements representing a script
+ * The interface `HtmlScriptElement` defines the behavior of elements representing a script
  * tag in an HTML file.
  * @see EmbeddedHtmlScriptElement
  * @see ExternalHtmlScriptElement
@@ -805,7 +830,7 @@
 abstract class HtmlScriptElement implements Element {
 }
 /**
- * The interface {@code ImportElement} defines the behavior of objects representing information
+ * The interface `ImportElement` defines the behavior of objects representing information
  * about a single import directive within a library.
  * @coverage dart.engine.element
  */
@@ -830,14 +855,14 @@
   LibraryElement get importedLibrary;
 
   /**
-   * Return the prefix that was specified as part of the import directive, or {@code null} if there
+   * Return the prefix that was specified as part of the import directive, or `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
+ * The interface `LabelElement` defines the behavior of elements representing a label
  * associated with a statement.
  * @coverage dart.engine.element
  */
@@ -850,7 +875,7 @@
   ExecutableElement get enclosingElement;
 }
 /**
- * The interface {@code LibraryElement} defines the behavior of elements representing a library.
+ * The interface `LibraryElement` defines the behavior of elements representing a library.
  * @coverage dart.engine.element
  */
 abstract class LibraryElement implements Element {
@@ -862,8 +887,8 @@
   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, or `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`main`.
    * @return the entry point for this library
    */
   FunctionElement get entryPoint;
@@ -883,7 +908,7 @@
   /**
    * 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.
+   * prefixes returned by [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;
@@ -896,20 +921,20 @@
 
   /**
    * 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.
+   * a `part` directive. This does not include the defining compilation unit that contains the`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
+   * Return an array containing elements for each of the prefixes used to `import` libraries
+   * into this library. Each prefix can be used in more than one `import` directive.
+   * @return the prefixes used to `import` libraries into this library
    */
   List<PrefixElement> get prefixes;
 
   /**
-   * Return the class defined in this library that has the given name, or {@code null} if this
+   * Return the class defined in this library that has the given name, or `null` if this
    * library does not define a class with the given name.
    * @param className the name of the class to be returned
    * @return the class with the given name that is defined in this library
@@ -917,73 +942,73 @@
   ClassElement getType(String className);
 
   /**
-   * Answer {@code true} if this library is an application that can be run in the browser.
-   * @return {@code true} if this library is an application that can be run in the browser
+   * Answer `true` if this library is an application that can be run in the browser.
+   * @return `true` if this library is an application that can be run in the browser
    */
-  bool isBrowserApplication();
+  bool get isBrowserApplication;
 
   /**
-   * Return {@code true} if this library is the dart:core library.
-   * @return {@code true} if this library is the dart:core library
+   * Return `true` if this library is the dart:core library.
+   * @return `true` if this library is the dart:core library
    */
-  bool isDartCore();
+  bool get isDartCore;
 
   /**
-   * Return {@code true} if this library is up to date with respect to the given time stamp. If any
+   * Return `true` if this library is up to date with respect to the given time stamp. If any
    * transitively referenced Source is newer than the time stamp, this method returns false.
    * @param timeStamp the time stamp to compare against
-   * @return {@code true} if this library is up to date with respect to the given time stamp
+   * @return `true` if this library is up to date with respect to the given time stamp
    */
   bool isUpToDate2(int timeStamp);
 }
 /**
- * The interface {@code LocalElement} defines the behavior of elements that can be (but are not
- * required to be) defined within a method or function (an {@link ExecutableElement}).
+ * The interface `LocalElement` defines the behavior of elements that can be (but are not
+ * required to be) defined within a method or function (an [ExecutableElement]).
  * @coverage dart.engine.element
  */
 abstract class LocalElement implements Element {
 
   /**
    * Return a source range that covers the approximate portion of the source in which the name of
-   * this element is visible, or {@code null} if there is no single range of characters within which
+   * this element is visible, or `null` if there is no single range of characters within which
    * the element name is visible.
-   * <ul>
-   * <li>For a local variable, this includes everything from the end of the variable's initializer
-   * to the end of the block that encloses the variable declaration.</li>
-   * <li>For a parameter, this includes the body of the method or function that declares the
-   * parameter.</li>
-   * <li>For a local function, this includes everything from the beginning of the function's body to
-   * the end of the block that encloses the function declaration.</li>
-   * <li>For top-level functions, {@code null} will be returned because they are potentially visible
-   * in multiple sources.</li>
-   * </ul>
+   *
+   * * For a local variable, this includes everything from the end of the variable's initializer
+   * to the end of the block that encloses the variable declaration.
+   * * For a parameter, this includes the body of the method or function that declares the
+   * parameter.
+   * * For a local function, this includes everything from the beginning of the function's body to
+   * the end of the block that encloses the function declaration.
+   * * For top-level functions, `null` will be returned because they are potentially visible
+   * in multiple sources.
+   *
    * @return the range of characters in which the name of this element is visible
    */
   SourceRange get visibleRange;
 }
 /**
- * The interface {@code LocalVariableElement} defines the behavior common to elements that represent
+ * The interface `LocalVariableElement` defines the behavior common to elements that represent
  * a local variable.
  * @coverage dart.engine.element
  */
 abstract class LocalVariableElement implements LocalElement, VariableElement {
 }
 /**
- * The interface {@code MethodElement} defines the behavior of elements that represent a method
+ * The interface `MethodElement` defines the behavior of elements that represent a method
  * defined within a type.
  * @coverage dart.engine.element
  */
 abstract class MethodElement implements ClassMemberElement, ExecutableElement {
 
   /**
-   * Return {@code true} if this method is abstract. Methods are abstract if they are not external
+   * Return `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
+   * @return `true` if this method is abstract
    */
-  bool isAbstract();
+  bool get isAbstract;
 }
 /**
- * The interface {@code MultiplyDefinedElement} defines the behavior of pseudo-elements that
+ * The interface `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
@@ -1000,7 +1025,7 @@
   List<Element> get conflictingElements;
 }
 /**
- * The interface {@code NamespaceCombinator} defines the behavior common to objects that control how
+ * The interface `NamespaceCombinator` defines the behavior common to objects that control how
  * namespaces are combined.
  * @coverage dart.engine.element
  */
@@ -1012,7 +1037,7 @@
   static final List<NamespaceCombinator> EMPTY_ARRAY = new List<NamespaceCombinator>(0);
 }
 /**
- * The interface {@code ParameterElement} defines the behavior of elements representing a parameter
+ * The interface `ParameterElement` defines the behavior of elements representing a parameter
  * defined within an executable element.
  * @coverage dart.engine.element
  */
@@ -1020,7 +1045,7 @@
 
   /**
    * Return a source range that covers the portion of the source in which the default value for this
-   * parameter is specified, or {@code null} if there is no default value.
+   * parameter is specified, or `null` if there is no default value.
    * @return the range of characters in which the default value of this parameter is specified
    */
   SourceRange get defaultValueRange;
@@ -1039,13 +1064,13 @@
   List<ParameterElement> get parameters;
 
   /**
-   * Return {@code true} if this parameter is an initializing formal parameter.
-   * @return {@code true} if this parameter is an initializing formal parameter
+   * Return `true` if this parameter is an initializing formal parameter.
+   * @return `true` if this parameter is an initializing formal parameter
    */
-  bool isInitializingFormal();
+  bool get isInitializingFormal;
 }
 /**
- * The interface {@code PrefixElement} defines the behavior common to elements that represent a
+ * The interface `PrefixElement` defines the behavior common to elements that represent a
  * prefix used to import one or more libraries into another library.
  * @coverage dart.engine.element
  */
@@ -1064,25 +1089,25 @@
   List<LibraryElement> get importedLibraries;
 }
 /**
- * The interface {@code PropertyAccessorElement} defines the behavior of elements representing a
+ * The interface `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>
+ *
+ * * Every explicit field is represented by a non-synthetic [FieldElement].
+ * * Every explicit field induces a getter and possibly a setter, both of which are represented by
+ * synthetic [PropertyAccessorElement]s.
+ * * Every explicit getter or setter is represented by a non-synthetic[PropertyAccessorElement].
+ * * Every explicit getter or setter (or pair thereof if they have the same name) induces a field
+ * that is represented by a synthetic [FieldElement].
+ *
  * @coverage dart.engine.element
  */
 abstract class PropertyAccessorElement implements ExecutableElement {
 
   /**
    * Return the accessor representing the getter that corresponds to (has the same name as) this
-   * setter, or {@code null} if this accessor is not a setter or if there is no corresponding
+   * setter, or `null` if this accessor is not a setter or if there is no corresponding
    * getter.
    * @return the getter that corresponds to this setter
    */
@@ -1090,7 +1115,7 @@
 
   /**
    * Return the accessor representing the setter that corresponds to (has the same name as) this
-   * getter, or {@code null} if this accessor is not a getter or if there is no corresponding
+   * getter, or `null` if this accessor is not a getter or if there is no corresponding
    * setter.
    * @return the setter that corresponds to this getter
    */
@@ -1104,38 +1129,38 @@
   PropertyInducingElement get variable;
 
   /**
-   * Return {@code true} if this accessor is abstract. Accessors are abstract if they are not
+   * Return `true` if this accessor is abstract. Accessors are abstract if they are not
    * external and have no body.
-   * @return {@code true} if this accessor is abstract
+   * @return `true` if this accessor is abstract
    */
-  bool isAbstract();
+  bool get isAbstract;
 
   /**
-   * Return {@code true} if this accessor represents a getter.
-   * @return {@code true} if this accessor represents a getter
+   * Return `true` if this accessor represents a getter.
+   * @return `true` if this accessor represents a getter
    */
-  bool isGetter();
+  bool get isGetter;
 
   /**
-   * Return {@code true} if this accessor represents a setter.
-   * @return {@code true} if this accessor represents a setter
+   * Return `true` if this accessor represents a setter.
+   * @return `true` if this accessor represents a setter
    */
-  bool isSetter();
+  bool get isSetter;
 }
 /**
- * The interface {@code PropertyInducingElement} defines the behavior of elements representing a
+ * The interface `PropertyInducingElement` defines the behavior of elements representing a
  * variable that has an associated getter and possibly a setter. Note that explicitly defined
- * variables implicitly define a synthetic getter and that non-{@code final} explicitly defined
+ * variables implicitly define a synthetic getter and that non-`final` explicitly defined
  * variables 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 variable is represented by a non-synthetic {@link PropertyInducingElement}.
- * <li>Every explicit variable 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
- * variable that is represented by a synthetic {@link PropertyInducingElement}.
- * </ul>
+ *
+ * * Every explicit variable is represented by a non-synthetic [PropertyInducingElement].
+ * * Every explicit variable induces a getter and possibly a setter, both of which are represented
+ * by synthetic [PropertyAccessorElement]s.
+ * * Every explicit getter or setter is represented by a non-synthetic[PropertyAccessorElement].
+ * * Every explicit getter or setter (or pair thereof if they have the same name) induces a
+ * variable that is represented by a synthetic [PropertyInducingElement].
+ *
  * @coverage dart.engine.element
  */
 abstract class PropertyInducingElement implements VariableElement {
@@ -1148,8 +1173,8 @@
   PropertyAccessorElement get getter;
 
   /**
-   * Return the setter associated with this variable, or {@code null} if the variable is effectively{@code final} and therefore does not have a setter associated with it. (This can happen either
-   * because the variable is explicitly defined as being {@code final} or because the variable is
+   * Return the setter associated with this variable, or `null` if the variable is effectively`final` and therefore does not have a setter associated with it. (This can happen either
+   * because the variable is explicitly defined as being `final` or because the variable is
    * induced by an explicit getter that does not have a corresponding setter.) If this variable was
    * explicitly defined (is not synthetic) then the setter associated with it will be synthetic.
    * @return the setter associated with this variable
@@ -1157,14 +1182,14 @@
   PropertyAccessorElement get setter;
 
   /**
-   * Return {@code true} if this element is a static element. A static element is an element that is
+   * Return `true` if this element is a static element. A static element is an element that is
    * not associated with a particular instance, but rather with an entire library or class.
-   * @return {@code true} if this executable element is a static element
+   * @return `true` if this executable element is a static element
    */
-  bool isStatic();
+  bool get isStatic;
 }
 /**
- * The interface {@code ShowElementCombinator} defines the behavior of combinators that cause some
+ * The interface `ShowElementCombinator` defines the behavior of combinators that cause some
  * of the names in a namespace to be visible (and the rest hidden) when being imported.
  * @coverage dart.engine.element
  */
@@ -1178,21 +1203,21 @@
   List<String> get shownNames;
 }
 /**
- * The interface {@code TopLevelVariableElement} defines the behavior of elements representing a
+ * The interface `TopLevelVariableElement` defines the behavior of elements representing a
  * top-level variable.
  * @coverage dart.engine.element
  */
 abstract class TopLevelVariableElement implements PropertyInducingElement {
 }
 /**
- * The interface {@code TypeVariableElement} defines the behavior of elements representing a type
+ * The interface `TypeVariableElement` defines the behavior of elements representing a type
  * variable.
  * @coverage dart.engine.element
  */
 abstract class TypeVariableElement implements Element {
 
   /**
-   * Return the type representing the bound associated with this variable, or {@code null} if this
+   * Return the type representing the bound associated with this variable, or `null` if this
    * variable does not have an explicit bound.
    * @return the type representing the bound associated with this variable
    */
@@ -1205,7 +1230,7 @@
   TypeVariableType get type;
 }
 /**
- * The interface {@code UndefinedElement} defines the behavior of pseudo-elements that represent
+ * The interface `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.
@@ -1214,27 +1239,27 @@
 abstract class UndefinedElement implements Element {
 }
 /**
- * The interface {@code UriReferencedElement} defines the behavior of objects included into a
+ * The interface `UriReferencedElement` defines the behavior of objects included into a
  * library using some URI.
  * @coverage dart.engine.element
  */
 abstract class UriReferencedElement implements Element {
 
   /**
-   * Return the URI that is used to include this element into the enclosing library, or {@code null}if this is the defining compilation unit of a library.
+   * Return the URI that is used to include this element into the enclosing library, or `null`if this is the defining compilation unit of a library.
    * @return the URI that is used to include this element into the enclosing library
    */
   String get uri;
 }
 /**
- * The interface {@code VariableElement} defines the behavior common to elements that represent a
+ * The interface `VariableElement` defines the behavior common to elements that represent a
  * variable.
  * @coverage dart.engine.element
  */
 abstract class VariableElement implements Element {
 
   /**
-   * Return a synthetic function representing this variable's initializer, or {@code null} if this
+   * Return a synthetic function representing this variable's initializer, or `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
@@ -1242,41 +1267,41 @@
   FunctionElement get initializer;
 
   /**
-   * Return the declared type of this variable, or {@code null} if the variable did not have a
+   * Return the declared type of this variable, or `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 was declared with the 'const' modifier.
-   * @return {@code true} if this variable was declared with the 'const' modifier
+   * Return `true` if this variable was declared with the 'const' modifier.
+   * @return `true` if this variable was declared with the 'const' modifier
    */
-  bool isConst();
+  bool get isConst;
 
   /**
-   * Return {@code true} if this variable was declared with the 'final' modifier. Variables that are
-   * declared with the 'const' modifier will return {@code false} even though they are implicitly
+   * Return `true` if this variable was declared with the 'final' modifier. Variables that are
+   * declared with the 'const' modifier will return `false` even though they are implicitly
    * final.
-   * @return {@code true} if this variable was declared with the 'final' modifier
+   * @return `true` if this variable was declared with the 'final' modifier
    */
-  bool isFinal();
+  bool get isFinal;
 }
 /**
- * Instances of the class {@code GeneralizingElementVisitor} implement an element visitor that will
- * recursively visit all of the elements in an element model (like instances of the class{@link RecursiveElementVisitor}). In addition, when an element of a specific type is visited not
+ * Instances of the class `GeneralizingElementVisitor` implement an element visitor that will
+ * recursively visit all of the elements in an element model (like instances of the class[RecursiveElementVisitor]). In addition, when an element of a specific type is visited not
  * only will the visit method for that specific type of element be invoked, but additional methods
  * for the supertypes of that element will also be invoked. For example, using an instance of this
- * class to visit a {@link MethodElement} will cause the method{@link #visitMethodElement(MethodElement)} to be invoked but will also cause the methods{@link #visitExecutableElement(ExecutableElement)} and {@link #visitElement(Element)} to be
+ * class to visit a [MethodElement] will cause the method[visitMethodElement] to be invoked but will also cause the methods[visitExecutableElement] and [visitElement] to be
  * subsequently invoked. This allows visitors to be written that visit all executable elements
- * without needing to override the visit method for each of the specific subclasses of{@link ExecutableElement}.
- * <p>
+ * without needing to override the visit method for each of the specific subclasses of[ExecutableElement].
+ *
  * Note, however, that unlike many visitors, element visitors visit objects based on the interfaces
  * implemented by those elements. Because interfaces form a graph structure rather than a tree
  * structure the way classes do, and because it is generally undesirable for an object to be visited
  * more than once, this class flattens the interface graph into a pseudo-tree. In particular, this
  * class treats elements as if the element types were structured in the following way:
- * <p>
+ *
  * <pre>
  * Element
  * ClassElement
@@ -1306,7 +1331,7 @@
  * ParameterElement
  * FieldFormalParameterElement
  * </pre>
- * <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 element to not be invoked and will cause the children of the visited node
@@ -1356,11 +1381,11 @@
   R visitVariableElement(VariableElement element) => visitElement(element);
 }
 /**
- * Instances of the class {@code RecursiveElementVisitor} implement an element visitor that will
+ * Instances of the class `RecursiveElementVisitor` implement an element visitor that will
  * recursively visit all of the element in an element model. For example, using an instance of this
- * class to visit a {@link CompilationUnitElement} will also cause all of the types in the
+ * class to visit a [CompilationUnitElement] will also cause all of the types in the
  * compilation unit to be visited.
- * <p>
+ *
  * Subclasses that override a visit method must either invoke the overridden visit method or must
  * explicitly ask the visited element to visit its children. Failure to do so will cause the
  * children of the visited element to not be visited.
@@ -1457,7 +1482,7 @@
   }
 }
 /**
- * Instances of the class {@code SimpleElementVisitor} implement an element visitor that will do
+ * Instances of the class `SimpleElementVisitor` implement an element visitor that will do
  * nothing when visiting an element. 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 element types.
@@ -1488,7 +1513,7 @@
   R visitTypeVariableElement(TypeVariableElement element) => null;
 }
 /**
- * Instances of the class {@code ClassElementImpl} implement a {@code ClassElement}.
+ * Instances of the class `ClassElementImpl` implement a `ClassElement`.
  * @coverage dart.engine.element
  */
 class ClassElementImpl extends ElementImpl implements ClassElement {
@@ -1525,7 +1550,7 @@
   List<MethodElement> _methods = MethodElementImpl.EMPTY_ARRAY;
 
   /**
-   * The superclass of the class, or {@code null} if the class does not have an explicit superclass.
+   * The superclass of the class, or `null` if the class does not have an explicit superclass.
    */
   InterfaceType _supertype;
 
@@ -1588,10 +1613,10 @@
   List<ConstructorElement> get constructors => _constructors;
 
   /**
-   * Given some name, this returns the {@link FieldElement} with the matching name, if there is no
-   * such field, then {@code null} is returned.
+   * Given some name, this returns the [FieldElement] with the matching name, if there is no
+   * such field, then `null` is returned.
    * @param name some name to lookup a field element with
-   * @return the matching field element, or {@code null} if no such element was found
+   * @return the matching field element, or `null` if no such element was found
    */
   FieldElement getField(String name2) {
     for (FieldElement fieldElement in _fields) {
@@ -1604,7 +1629,7 @@
   List<FieldElement> get fields => _fields;
   PropertyAccessorElement getGetter(String getterName) {
     for (PropertyAccessorElement accessor in _accessors) {
-      if (accessor.isGetter() && accessor.name == getterName) {
+      if (accessor.isGetter && accessor.name == getterName) {
         return accessor;
       }
     }
@@ -1636,7 +1661,7 @@
       setterName += '=';
     }
     for (PropertyAccessorElement accessor in _accessors) {
-      if (accessor.isSetter() && accessor.name == setterName) {
+      if (accessor.isSetter && accessor.name == setterName) {
         return accessor;
       }
     }
@@ -1654,6 +1679,14 @@
     }
     return null;
   }
+  bool hasDefaultConstructor() {
+    for (ConstructorElement constructor in constructors) {
+      if (constructor.isDefaultConstructor) {
+        return true;
+      }
+    }
+    return false;
+  }
   bool hasNonFinalField() {
     List<ClassElement> classesToVisit = new List<ClassElement>();
     Set<ClassElement> visitedClasses = new Set<ClassElement>();
@@ -1662,7 +1695,7 @@
       ClassElement currentElement = classesToVisit.removeAt(0);
       if (javaSetAdd(visitedClasses, currentElement)) {
         for (FieldElement field in currentElement.fields) {
-          if (!field.isFinal() && !field.isConst() && !field.isStatic() && !field.isSynthetic()) {
+          if (!field.isFinal && !field.isConst && !field.isStatic && !field.isSynthetic) {
             return true;
           }
         }
@@ -1682,9 +1715,9 @@
     return false;
   }
   bool hasReferenceToSuper() => hasModifier(Modifier.REFERENCES_SUPER);
-  bool isAbstract() => hasModifier(Modifier.ABSTRACT);
-  bool isTypedef() => hasModifier(Modifier.TYPEDEF);
-  bool isValidMixin() => hasModifier(Modifier.MIXIN);
+  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
+  bool get isTypedef => hasModifier(Modifier.TYPEDEF);
+  bool get isValidMixin => hasModifier(Modifier.MIXIN);
   PropertyAccessorElement lookUpGetter(String getterName, LibraryElement library) {
     Set<ClassElement> visitedClasses = new Set<ClassElement>();
     ClassElement currentElement = this;
@@ -1766,7 +1799,7 @@
 
   /**
    * Set whether this class is abstract to correspond to the given value.
-   * @param isAbstract {@code true} if the class is abstract
+   * @param isAbstract `true` if the class is abstract
    */
   void set abstract(bool isAbstract) {
     setModifier(Modifier.ABSTRACT, isAbstract);
@@ -1807,7 +1840,7 @@
 
   /**
    * Set whether this class references 'super' to the given value.
-   * @param isReferencedSuper {@code true} references 'super'
+   * @param isReferencedSuper `true` references 'super'
    */
   void set hasReferenceToSuper2(bool isReferencedSuper) {
     setModifier(Modifier.REFERENCES_SUPER, isReferencedSuper);
@@ -1859,7 +1892,7 @@
 
   /**
    * Set whether this class is defined by a typedef construct to correspond to the given value.
-   * @param isTypedef {@code true} if the class is defined by a typedef construct
+   * @param isTypedef `true` if the class is defined by a typedef construct
    */
   void set typedef(bool isTypedef) {
     setModifier(Modifier.TYPEDEF, isTypedef);
@@ -1878,7 +1911,7 @@
 
   /**
    * Set whether this class is a valid mixin to correspond to the given value.
-   * @param isValidMixin {@code true} if this class can be used as a mixin
+   * @param isValidMixin `true` if this class can be used as a mixin
    */
   void set validMixin(bool isValidMixin) {
     setModifier(Modifier.MIXIN, isValidMixin);
@@ -1940,7 +1973,7 @@
   }
 }
 /**
- * Instances of the class {@code CompilationUnitElementImpl} implement a{@link CompilationUnitElement}.
+ * Instances of the class `CompilationUnitElementImpl` implement a[CompilationUnitElement].
  * @coverage dart.engine.element
  */
 class CompilationUnitElementImpl extends ElementImpl implements CompilationUnitElement {
@@ -1982,7 +2015,7 @@
   List<ClassElement> _types = ClassElementImpl.EMPTY_ARRAY;
 
   /**
-   * The URI that is specified by the "part" directive in the enclosing library, or {@code null} if
+   * The URI that is specified by the "part" directive in the enclosing library, or `null` if
    * this is the defining compilation unit of a library.
    */
   String _uri;
@@ -2131,7 +2164,7 @@
   }
 }
 /**
- * Instances of the class {@code ConstFieldElementImpl} implement a {@code FieldElement} for a
+ * Instances of the class `ConstFieldElementImpl` implement a `FieldElement` for a
  * 'const' field that has an initializer.
  */
 class ConstFieldElementImpl extends FieldElementImpl {
@@ -2153,7 +2186,7 @@
   }
 }
 /**
- * Instances of the class {@code ConstLocalVariableElementImpl} implement a{@code LocalVariableElement} for a local 'const' variable that has an initializer.
+ * Instances of the class `ConstLocalVariableElementImpl` implement a`LocalVariableElement` for a local 'const' variable that has an initializer.
  * @coverage dart.engine.element
  */
 class ConstLocalVariableElementImpl extends LocalVariableElementImpl {
@@ -2175,30 +2208,7 @@
   }
 }
 /**
- * Instances of the class {@code ConstParameterElementImpl} implement a {@code ParameterElement} for
- * a 'const' parameter that has an initializer.
- * @coverage dart.engine.element
- */
-class ConstParameterElementImpl extends ParameterElementImpl {
-
-  /**
-   * The result of evaluating this variable's initializer.
-   */
-  EvaluationResultImpl _result;
-
-  /**
-   * Initialize a newly created parameter element to have the given name.
-   * @param name the name of this element
-   */
-  ConstParameterElementImpl(Identifier name) : super(name) {
-  }
-  EvaluationResultImpl get evaluationResult => _result;
-  void set evaluationResult(EvaluationResultImpl result2) {
-    this._result = result2;
-  }
-}
-/**
- * Instances of the class {@code ConstTopLevelVariableElementImpl} implement a{@code TopLevelVariableElement} for a top-level 'const' variable that has an initializer.
+ * Instances of the class `ConstTopLevelVariableElementImpl` implement a`TopLevelVariableElement` for a top-level 'const' variable that has an initializer.
  */
 class ConstTopLevelVariableElementImpl extends TopLevelVariableElementImpl {
 
@@ -2219,7 +2229,7 @@
   }
 }
 /**
- * Instances of the class {@code ConstructorElementImpl} implement a {@code ConstructorElement}.
+ * Instances of the class `ConstructorElementImpl` implement a `ConstructorElement`.
  * @coverage dart.engine.element
  */
 class ConstructorElementImpl extends ExecutableElementImpl implements ConstructorElement {
@@ -2244,13 +2254,25 @@
   ClassElement get enclosingElement => super.enclosingElement as ClassElement;
   ElementKind get kind => ElementKind.CONSTRUCTOR;
   ConstructorElement get redirectedConstructor => _redirectedConstructor;
-  bool isConst() => hasModifier(Modifier.CONST);
-  bool isFactory() => hasModifier(Modifier.FACTORY);
-  bool isStatic() => false;
+  bool get isConst => hasModifier(Modifier.CONST);
+  bool get isDefaultConstructor {
+    String name = this.name;
+    if (name != null && name.length != 0) {
+      return false;
+    }
+    for (ParameterElement parameter in parameters) {
+      if (identical(parameter.parameterKind, ParameterKind.REQUIRED)) {
+        return false;
+      }
+    }
+    return true;
+  }
+  bool get isFactory => hasModifier(Modifier.FACTORY);
+  bool get isStatic => false;
 
   /**
    * Set whether this constructor represents a 'const' constructor to the given value.
-   * @param isConst {@code true} if this constructor represents a 'const' constructor
+   * @param isConst `true` if this constructor represents a 'const' constructor
    */
   void set const2(bool isConst) {
     setModifier(Modifier.CONST, isConst);
@@ -2258,7 +2280,7 @@
 
   /**
    * Set whether this constructor represents a factory method to the given value.
-   * @param isFactory {@code true} if this constructor represents a factory method
+   * @param isFactory `true` if this constructor represents a factory method
    */
   void set factory(bool isFactory) {
     setModifier(Modifier.FACTORY, isFactory);
@@ -2282,8 +2304,52 @@
   }
 }
 /**
- * Instances of the class {@code DynamicElementImpl} represent the synthetic element representing
- * the declaration of the type {@code dynamic}.
+ * Instances of the class `DefaultFieldFormalParameterElementImpl` implement a`FieldFormalParameterElementImpl` for parameters that have an initializer.
+ * @coverage dart.engine.element
+ */
+class DefaultFieldFormalParameterElementImpl extends FieldFormalParameterElementImpl {
+
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+
+  /**
+   * Initialize a newly created parameter element to have the given name.
+   * @param name the name of this element
+   */
+  DefaultFieldFormalParameterElementImpl(Identifier name) : super(name) {
+  }
+  EvaluationResultImpl get evaluationResult => _result;
+  void set evaluationResult(EvaluationResultImpl result2) {
+    this._result = result2;
+  }
+}
+/**
+ * Instances of the class `DefaultParameterElementImpl` implement a `ParameterElement`for parameters that have an initializer.
+ * @coverage dart.engine.element
+ */
+class DefaultParameterElementImpl extends ParameterElementImpl {
+
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+
+  /**
+   * Initialize a newly created parameter element to have the given name.
+   * @param name the name of this element
+   */
+  DefaultParameterElementImpl(Identifier name) : super(name) {
+  }
+  EvaluationResultImpl get evaluationResult => _result;
+  void set evaluationResult(EvaluationResultImpl result2) {
+    this._result = result2;
+  }
+}
+/**
+ * Instances of the class `DynamicElementImpl` represent the synthetic element representing
+ * the declaration of the type `dynamic`.
  * @coverage dart.engine.element
  */
 class DynamicElementImpl extends ElementImpl {
@@ -2302,7 +2368,7 @@
   /**
    * 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 method {@link #getInstance()}.
+   * of this class should be accessed through the method [getInstance].
    */
   DynamicElementImpl() : super.con2(Keyword.DYNAMIC.syntax, -1) {
     setModifier(Modifier.SYNTHETIC, true);
@@ -2325,7 +2391,7 @@
   }
 }
 /**
- * Instances of the class {@code ElementAnnotationImpl} implement an {@link ElementAnnotation}.
+ * Instances of the class `ElementAnnotationImpl` implement an [ElementAnnotation].
  * @coverage dart.engine.element
  */
 class ElementAnnotationImpl implements ElementAnnotation {
@@ -2352,14 +2418,14 @@
   String toString() => "@${_element.toString()}";
 }
 /**
- * The abstract class {@code ElementImpl} implements the behavior common to objects that implement
- * an {@link Element}.
+ * The abstract class `ElementImpl` implements the behavior common to objects that implement
+ * an [Element].
  * @coverage dart.engine.element
  */
 abstract class ElementImpl implements Element {
 
   /**
-   * The enclosing element of this element, or {@code null} if this element is at the root of the
+   * The enclosing element of this element, or `null` if this element is at the root of the
    * element structure.
    */
   ElementImpl _enclosingElement;
@@ -2395,10 +2461,10 @@
    * @param name the name of this element
    */
   ElementImpl.con1(Identifier name2) {
-    _jtd_constructor_194_impl(name2);
+    _jtd_constructor_195_impl(name2);
   }
-  _jtd_constructor_194_impl(Identifier name2) {
-    _jtd_constructor_195_impl(name2 == null ? "" : name2.name, name2 == null ? -1 : name2.offset);
+  _jtd_constructor_195_impl(Identifier name2) {
+    _jtd_constructor_196_impl(name2 == null ? "" : name2.name, name2 == null ? -1 : name2.offset);
   }
 
   /**
@@ -2408,9 +2474,9 @@
    * declaration of this element
    */
   ElementImpl.con2(String name2, int nameOffset2) {
-    _jtd_constructor_195_impl(name2, nameOffset2);
+    _jtd_constructor_196_impl(name2, nameOffset2);
   }
-  _jtd_constructor_195_impl(String name2, int nameOffset2) {
+  _jtd_constructor_196_impl(String name2, int nameOffset2) {
     this._name = StringUtilities.intern(name2);
     this._nameOffset = nameOffset2;
   }
@@ -2431,7 +2497,7 @@
   }
 
   /**
-   * Return the child of this element that is uniquely identified by the given identifier, or{@code null} if there is no such child.
+   * Return the child of this element that is uniquely identified by the given identifier, or`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
    */
@@ -2467,7 +2533,7 @@
     }
     return true;
   }
-  bool isSynthetic() => hasModifier(Modifier.SYNTHETIC);
+  bool get isSynthetic => hasModifier(Modifier.SYNTHETIC);
 
   /**
    * Set the metadata associate with this element to the given array of annotations.
@@ -2489,7 +2555,7 @@
 
   /**
    * Set whether this element is synthetic to correspond to the given value.
-   * @param isSynthetic {@code true} if the element is synthetic
+   * @param isSynthetic `true` if the element is synthetic
    */
   void set synthetic(bool isSynthetic) {
     setModifier(Modifier.SYNTHETIC, isSynthetic);
@@ -2524,14 +2590,14 @@
   String get identifier => name;
 
   /**
-   * Return {@code true} if this element has the given modifier associated with it.
+   * Return `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
+   * @return `true` if this element has the given modifier associated with it
    */
   bool hasModifier(Modifier modifier) => _modifiers != null && _modifiers.contains(modifier);
 
   /**
-   * If the given child is not {@code null}, use the given visitor to visit it.
+   * If the given child is not `null`, use the given visitor to visit it.
    * @param child the child to be visited
    * @param visitor the visitor to be used to visit the child
    */
@@ -2566,7 +2632,7 @@
    * 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
+   * @param value `true` if the modifier is to be associated with this element
    */
   void setModifier(Modifier modifier, bool value) {
     if (value) {
@@ -2585,7 +2651,7 @@
   }
 }
 /**
- * Instances of the class {@code ElementLocationImpl} implement an {@link ElementLocation}.
+ * Instances of the class `ElementLocationImpl` implement an [ElementLocation].
  * @coverage dart.engine.element
  */
 class ElementLocationImpl implements ElementLocation {
@@ -2605,9 +2671,9 @@
    * @param element the element whose location is being represented
    */
   ElementLocationImpl.con1(Element element) {
-    _jtd_constructor_196_impl(element);
+    _jtd_constructor_197_impl(element);
   }
-  _jtd_constructor_196_impl(Element element) {
+  _jtd_constructor_197_impl(Element element) {
     List<String> components = new List<String>();
     Element ancestor = element;
     while (ancestor != null) {
@@ -2622,9 +2688,9 @@
    * @param encoding the encoded form of a location
    */
   ElementLocationImpl.con2(String encoding) {
-    _jtd_constructor_197_impl(encoding);
+    _jtd_constructor_198_impl(encoding);
   }
-  _jtd_constructor_197_impl(String encoding) {
+  _jtd_constructor_198_impl(String encoding) {
     this._components = decode(encoding);
   }
   bool operator ==(Object object) {
@@ -2719,11 +2785,11 @@
   }
 
   /**
-   * Return {@code true} if the given components, when interpreted to be encoded sources with a
+   * Return `true` if the given components, when interpreted to be encoded sources with a
    * leading source type indicator, are equal when the source type's are ignored.
    * @param left the left component being compared
    * @param right the right component being compared
-   * @return {@code true} if the given components are equal when the source type's are ignored
+   * @return `true` if the given components are equal when the source type's are ignored
    */
   bool equalSourceComponents(String left, String right) {
     if (left == null) {
@@ -2738,7 +2804,7 @@
   }
 }
 /**
- * Instances of the class {@code EmbeddedHtmlScriptElementImpl} implement an{@link EmbeddedHtmlScriptElement}.
+ * Instances of the class `EmbeddedHtmlScriptElementImpl` implement an[EmbeddedHtmlScriptElement].
  * @coverage dart.engine.element
  */
 class EmbeddedHtmlScriptElementImpl extends HtmlScriptElementImpl implements EmbeddedHtmlScriptElement {
@@ -2750,7 +2816,7 @@
 
   /**
    * Initialize a newly created script element to have the specified tag name and offset.
-   * @param node the XML node from which this element is derived (not {@code null})
+   * @param node the XML node from which this element is derived (not `null`)
    */
   EmbeddedHtmlScriptElementImpl(XmlTagNode node) : super(node) {
   }
@@ -2760,7 +2826,7 @@
 
   /**
    * Set the script library defined by the script tag's content.
-   * @param scriptLibrary the library or {@code null} if none
+   * @param scriptLibrary the library or `null` if none
    */
   void set scriptLibrary(LibraryElementImpl scriptLibrary2) {
     scriptLibrary2.enclosingElement = this;
@@ -2771,7 +2837,7 @@
   }
 }
 /**
- * The abstract class {@code ExecutableElementImpl} implements the behavior common to{@code ExecutableElement}s.
+ * The abstract class `ExecutableElementImpl` implements the behavior common to`ExecutableElement`s.
  * @coverage dart.engine.element
  */
 abstract class ExecutableElementImpl extends ElementImpl implements ExecutableElement {
@@ -2797,6 +2863,11 @@
   List<ParameterElement> _parameters = ParameterElementImpl.EMPTY_ARRAY;
 
   /**
+   * The return type defined by this executable element.
+   */
+  Type2 _returnType;
+
+  /**
    * The type of function defined by this executable element.
    */
   FunctionType _type;
@@ -2811,9 +2882,9 @@
    * @param name the name of this element
    */
   ExecutableElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_199_impl(name);
+    _jtd_constructor_200_impl(name);
   }
-  _jtd_constructor_199_impl(Identifier name) {
+  _jtd_constructor_200_impl(Identifier name) {
   }
 
   /**
@@ -2823,9 +2894,9 @@
    * declaration of this element
    */
   ExecutableElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset) {
-    _jtd_constructor_200_impl(name, nameOffset);
+    _jtd_constructor_201_impl(name, nameOffset);
   }
-  _jtd_constructor_200_impl(String name, int nameOffset) {
+  _jtd_constructor_201_impl(String name, int nameOffset) {
   }
   ElementImpl getChild(String identifier2) {
     for (ExecutableElement function in _functions) {
@@ -2854,8 +2925,9 @@
   List<LabelElement> get labels => _labels;
   List<LocalVariableElement> get localVariables => _localVariables;
   List<ParameterElement> get parameters => _parameters;
+  Type2 get returnType => _returnType;
   FunctionType get type => _type;
-  bool isOperator() => false;
+  bool get isOperator => false;
 
   /**
    * Set the functions defined within this executable element to the given functions.
@@ -2902,6 +2974,14 @@
   }
 
   /**
+   * Set the return type defined by this executable element.
+   * @param returnType the return type defined by this executable element
+   */
+  void set returnType(Type2 returnType2) {
+    this._returnType = returnType2;
+  }
+
+  /**
    * 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
    */
@@ -2932,7 +3012,7 @@
   }
 }
 /**
- * Instances of the class {@code ExportElementImpl} implement an {@link ExportElement}.
+ * Instances of the class `ExportElementImpl` implement an [ExportElement].
  * @coverage dart.engine.element
  */
 class ExportElementImpl extends ElementImpl implements ExportElement {
@@ -2996,19 +3076,19 @@
   String get identifier => _exportedLibrary.name;
 }
 /**
- * Instances of the class {@code ExternalHtmlScriptElementImpl} implement an{@link ExternalHtmlScriptElement}.
+ * Instances of the class `ExternalHtmlScriptElementImpl` implement an[ExternalHtmlScriptElement].
  * @coverage dart.engine.element
  */
 class ExternalHtmlScriptElementImpl extends HtmlScriptElementImpl implements ExternalHtmlScriptElement {
 
   /**
-   * The source specified in the {@code source} attribute or {@code null} if unspecified.
+   * The source specified in the `source` attribute or `null` if unspecified.
    */
   Source _scriptSource;
 
   /**
    * Initialize a newly created script element to have the specified tag name and offset.
-   * @param node the XML node from which this element is derived (not {@code null})
+   * @param node the XML node from which this element is derived (not `null`)
    */
   ExternalHtmlScriptElementImpl(XmlTagNode node) : super(node) {
   }
@@ -3017,15 +3097,15 @@
   Source get scriptSource => _scriptSource;
 
   /**
-   * Set the source specified in the {@code source} attribute.
-   * @param scriptSource the script source or {@code null} if unspecified
+   * Set the source specified in the `source` attribute.
+   * @param scriptSource the script source or `null` if unspecified
    */
   void set scriptSource(Source scriptSource2) {
     this._scriptSource = scriptSource2;
   }
 }
 /**
- * Instances of the class {@code FieldElementImpl} implement a {@code FieldElement}.
+ * Instances of the class `FieldElementImpl` implement a `FieldElement`.
  * @coverage dart.engine.element
  */
 class FieldElementImpl extends PropertyInducingElementImpl implements FieldElement {
@@ -3040,9 +3120,9 @@
    * @param name the name of this element
    */
   FieldElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_203_impl(name);
+    _jtd_constructor_204_impl(name);
   }
-  _jtd_constructor_203_impl(Identifier name) {
+  _jtd_constructor_204_impl(Identifier name) {
   }
 
   /**
@@ -3050,25 +3130,25 @@
    * @param name the name of this element
    */
   FieldElementImpl.con2(String name) : super.con2(name) {
-    _jtd_constructor_204_impl(name);
+    _jtd_constructor_205_impl(name);
   }
-  _jtd_constructor_204_impl(String name) {
+  _jtd_constructor_205_impl(String name) {
   }
   accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
   ClassElement get enclosingElement => super.enclosingElement as ClassElement;
   ElementKind get kind => ElementKind.FIELD;
-  bool isStatic() => hasModifier(Modifier.STATIC);
+  bool get isStatic => hasModifier(Modifier.STATIC);
 
   /**
    * Set whether this field is static to correspond to the given value.
-   * @param isStatic {@code true} if the field is static
+   * @param isStatic `true` if the field is static
    */
   void set static(bool isStatic) {
     setModifier(Modifier.STATIC, isStatic);
   }
 }
 /**
- * Instances of the class {@code FieldFormalParameterElementImpl} extend{@link ParameterElementImpl} to provide the additional information of the {@link FieldElement}associated with the parameter.
+ * Instances of the class `FieldFormalParameterElementImpl` extend[ParameterElementImpl] to provide the additional information of the [FieldElement]associated with the parameter.
  * @coverage dart.engine.element
  */
 class FieldFormalParameterElementImpl extends ParameterElementImpl implements FieldFormalParameterElement {
@@ -3086,7 +3166,7 @@
   }
   accept(ElementVisitor visitor) => visitor.visitFieldFormalParameterElement(this);
   FieldElement get field => _field;
-  bool isInitializingFormal() => true;
+  bool get isInitializingFormal => true;
 
   /**
    * Set the field element associated with this field formal parameter to the given element.
@@ -3097,7 +3177,7 @@
   }
 }
 /**
- * Instances of the class {@code FunctionElementImpl} implement a {@code FunctionElement}.
+ * Instances of the class `FunctionElementImpl` implement a `FunctionElement`.
  * @coverage dart.engine.element
  */
 class FunctionElementImpl extends ExecutableElementImpl implements FunctionElement {
@@ -3108,7 +3188,7 @@
   int _visibleRangeOffset = 0;
 
   /**
-   * The length of the visible range for this element, or {@code -1} if this element does not have a
+   * The length of the visible range for this element, or `-1` if this element does not have a
    * visible range.
    */
   int _visibleRangeLength = -1;
@@ -3122,9 +3202,9 @@
    * Initialize a newly created synthetic function element.
    */
   FunctionElementImpl() : super.con2("", -1) {
-    _jtd_constructor_206_impl();
+    _jtd_constructor_207_impl();
   }
-  _jtd_constructor_206_impl() {
+  _jtd_constructor_207_impl() {
     synthetic = true;
   }
 
@@ -3133,9 +3213,9 @@
    * @param name the name of this element
    */
   FunctionElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_207_impl(name);
+    _jtd_constructor_208_impl(name);
   }
-  _jtd_constructor_207_impl(Identifier name) {
+  _jtd_constructor_208_impl(Identifier name) {
   }
 
   /**
@@ -3145,9 +3225,9 @@
    * declaration of this element
    */
   FunctionElementImpl.con2(int nameOffset) : super.con2("", nameOffset) {
-    _jtd_constructor_208_impl(nameOffset);
+    _jtd_constructor_209_impl(nameOffset);
   }
-  _jtd_constructor_208_impl(int nameOffset) {
+  _jtd_constructor_209_impl(int nameOffset) {
   }
   accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
   String get identifier => "${name}@${nameOffset}";
@@ -3158,13 +3238,13 @@
     }
     return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
   }
-  bool isStatic() => enclosingElement is CompilationUnitElement;
+  bool get isStatic => enclosingElement is CompilationUnitElement;
 
   /**
    * Set the visible range for this element to the range starting at the given offset with the given
    * length.
    * @param offset the offset to the beginning of the visible range for this element
-   * @param length the length of the visible range for this element, or {@code -1} if this element
+   * @param length the length of the visible range for this element, or `-1` if this element
    * does not have a visible range
    */
   void setVisibleRange(int offset, int length) {
@@ -3180,7 +3260,7 @@
   }
 }
 /**
- * Instances of the class {@code FunctionTypeAliasElementImpl} implement a{@code FunctionTypeAliasElement}.
+ * Instances of the class `FunctionTypeAliasElementImpl` implement a`FunctionTypeAliasElement`.
  * @coverage dart.engine.element
  */
 class FunctionTypeAliasElementImpl extends ElementImpl implements FunctionTypeAliasElement {
@@ -3191,6 +3271,11 @@
   List<ParameterElement> _parameters = ParameterElementImpl.EMPTY_ARRAY;
 
   /**
+   * The return type defined by this type alias.
+   */
+  Type2 _returnType;
+
+  /**
    * The type of function defined by this type alias.
    */
   FunctionType _type;
@@ -3228,6 +3313,7 @@
   CompilationUnitElement get enclosingElement => super.enclosingElement as CompilationUnitElement;
   ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
   List<ParameterElement> get parameters => _parameters;
+  Type2 get returnType => _returnType;
   FunctionType get type => _type;
   List<TypeVariableElement> get typeVariables => _typeVariables;
 
@@ -3245,6 +3331,14 @@
   }
 
   /**
+   * Set the return type defined by this type alias.
+   * @param returnType the return type defined by this type alias
+   */
+  void set returnType(Type2 returnType2) {
+    this._returnType = returnType2;
+  }
+
+  /**
    * 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
    */
@@ -3297,7 +3391,7 @@
   }
 }
 /**
- * Instances of the class {@code HideElementCombinatorImpl} implement a{@link HideElementCombinator}.
+ * Instances of the class `HideElementCombinatorImpl` implement a[HideElementCombinator].
  * @coverage dart.engine.element
  */
 class HideElementCombinatorImpl implements HideElementCombinator {
@@ -3331,7 +3425,7 @@
   }
 }
 /**
- * Instances of the class {@code HtmlElementImpl} implement an {@link HtmlElement}.
+ * Instances of the class `HtmlElementImpl` implement an [HtmlElement].
  * @coverage dart.engine.element
  */
 class HtmlElementImpl extends ElementImpl implements HtmlElement {
@@ -3406,7 +3500,7 @@
   }
 }
 /**
- * Instances of the class {@code HtmlScriptElementImpl} implement an {@link HtmlScriptElement}.
+ * Instances of the class `HtmlScriptElementImpl` implement an [HtmlScriptElement].
  * @coverage dart.engine.element
  */
 abstract class HtmlScriptElementImpl extends ElementImpl implements HtmlScriptElement {
@@ -3418,13 +3512,13 @@
 
   /**
    * Initialize a newly created script element to have the specified tag name and offset.
-   * @param node the XML node from which this element is derived (not {@code null})
+   * @param node the XML node from which this element is derived (not `null`)
    */
   HtmlScriptElementImpl(XmlTagNode node) : super.con2(node.tag.lexeme, node.tag.offset) {
   }
 }
 /**
- * Instances of the class {@code ImportElementImpl} implement an {@link ImportElement}.
+ * Instances of the class `ImportElementImpl` implement an [ImportElement].
  * @coverage dart.engine.element
  */
 class ImportElementImpl extends ElementImpl implements ImportElement {
@@ -3446,7 +3540,7 @@
   List<NamespaceCombinator> _combinators = NamespaceCombinator.EMPTY_ARRAY;
 
   /**
-   * The prefix that was specified as part of the import directive, or {@code null} if there was no
+   * The prefix that was specified as part of the import directive, or `null` if there was no
    * prefix specified.
    */
   PrefixElement _prefix;
@@ -3507,18 +3601,18 @@
   String get identifier => ((_importedLibrary as LibraryElementImpl)).identifier;
 }
 /**
- * Instances of the class {@code LabelElementImpl} implement a {@code LabelElement}.
+ * Instances of the class `LabelElementImpl` implement a `LabelElement`.
  * @coverage dart.engine.element
  */
 class LabelElementImpl extends ElementImpl implements LabelElement {
 
   /**
-   * A flag indicating whether this label is associated with a {@code switch} statement.
+   * A flag indicating whether this label is associated with a `switch` statement.
    */
   bool _onSwitchStatement = false;
 
   /**
-   * A flag indicating whether this label is associated with a {@code switch} member ({@code case}or {@code default}).
+   * A flag indicating whether this label is associated with a `switch` member (`case`or `default`).
    */
   bool _onSwitchMember = false;
 
@@ -3530,8 +3624,8 @@
   /**
    * 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
+   * @param onSwitchStatement `true` if this label is associated with a `switch`statement
+   * @param onSwitchMember `true` if this label is associated with a `switch` member
    */
   LabelElementImpl(Identifier name, bool onSwitchStatement, bool onSwitchMember) : super.con1(name) {
     this._onSwitchStatement = onSwitchStatement;
@@ -3542,19 +3636,19 @@
   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
+   * Return `true` if this label is associated with a `switch` member (`case` or`default`).
+   * @return `true` if this label is associated with a `switch` member
    */
-  bool isOnSwitchMember() => _onSwitchMember;
+  bool get 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
+   * Return `true` if this label is associated with a `switch` statement.
+   * @return `true` if this label is associated with a `switch` statement
    */
-  bool isOnSwitchStatement() => _onSwitchStatement;
+  bool get isOnSwitchStatement => _onSwitchStatement;
 }
 /**
- * Instances of the class {@code LibraryElementImpl} implement a {@code LibraryElement}.
+ * Instances of the class `LibraryElementImpl` implement a `LibraryElement`.
  * @coverage dart.engine.element
  */
 class LibraryElementImpl extends ElementImpl implements LibraryElement {
@@ -3606,7 +3700,7 @@
   CompilationUnitElement _definingCompilationUnit;
 
   /**
-   * The entry point for this library, or {@code null} if this library does not have an entry point.
+   * The entry point for this library, or `null` if this library does not have an entry point.
    */
   FunctionElement _entryPoint;
 
@@ -3621,7 +3715,7 @@
   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.
+   * An array containing all of the compilation units that are included in this library using a`part` directive.
    */
   List<CompilationUnitElement> _parts = CompilationUnitElementImpl.EMPTY_ARRAY;
 
@@ -3715,8 +3809,8 @@
     return null;
   }
   int get hashCode => _definingCompilationUnit.hashCode;
-  bool isBrowserApplication() => _entryPoint != null && isOrImportsBrowserLibrary();
-  bool isDartCore() => name == "dart.core";
+  bool get isBrowserApplication => _entryPoint != null && isOrImportsBrowserLibrary;
+  bool get isDartCore => name == "dart.core";
   bool isUpToDate2(int timeStamp) {
     Set<LibraryElement> visitedLibraries = new Set();
     return isUpToDate(this, timeStamp, visitedLibraries);
@@ -3766,8 +3860,8 @@
   }
 
   /**
-   * 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
+   * Set the compilation units that are included in this library using a `part` directive.
+   * @param parts the compilation units that are included in this library using a `part`directive
    */
   void set parts(List<CompilationUnitElement> parts2) {
     for (CompilationUnitElement compilationUnit in parts2) {
@@ -3784,10 +3878,10 @@
   }
 
   /**
-   * Answer {@code true} if the receiver directly or indirectly imports the dart:html libraries.
-   * @return {@code true} if the receiver directly or indirectly imports the dart:html libraries
+   * Answer `true` if the receiver directly or indirectly imports the dart:html libraries.
+   * @return `true` if the receiver directly or indirectly imports the dart:html libraries
    */
-  bool isOrImportsBrowserLibrary() {
+  bool get isOrImportsBrowserLibrary {
     List<LibraryElement> visited = new List<LibraryElement>();
     Source htmlLibSource = _context.sourceFactory.forUri(DartSdk.DART_HTML);
     visited.add(this);
@@ -3812,7 +3906,7 @@
   }
 }
 /**
- * Instances of the class {@code LocalVariableElementImpl} implement a {@code LocalVariableElement}.
+ * Instances of the class `LocalVariableElementImpl` implement a `LocalVariableElement`.
  * @coverage dart.engine.element
  */
 class LocalVariableElementImpl extends VariableElementImpl implements LocalVariableElement {
@@ -3823,7 +3917,7 @@
   int _visibleRangeOffset = 0;
 
   /**
-   * The length of the visible range for this element, or {@code -1} if this element does not have a
+   * The length of the visible range for this element, or `-1` if this element does not have a
    * visible range.
    */
   int _visibleRangeLength = -1;
@@ -3852,7 +3946,7 @@
    * Set the visible range for this element to the range starting at the given offset with the given
    * length.
    * @param offset the offset to the beginning of the visible range for this element
-   * @param length the length of the visible range for this element, or {@code -1} if this element
+   * @param length the length of the visible range for this element, or `-1` if this element
    * does not have a visible range
    */
   void setVisibleRange(int offset, int length) {
@@ -3867,7 +3961,7 @@
   String get identifier => "${super.identifier}@${nameOffset}";
 }
 /**
- * Instances of the class {@code MethodElementImpl} implement a {@code MethodElement}.
+ * Instances of the class `MethodElementImpl` implement a `MethodElement`.
  * @coverage dart.engine.element
  */
 class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
@@ -3882,9 +3976,9 @@
    * @param name the name of this element
    */
   MethodElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_217_impl(name);
+    _jtd_constructor_218_impl(name);
   }
-  _jtd_constructor_217_impl(Identifier name) {
+  _jtd_constructor_218_impl(Identifier name) {
   }
 
   /**
@@ -3894,24 +3988,24 @@
    * declaration of this element
    */
   MethodElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset) {
-    _jtd_constructor_218_impl(name, nameOffset);
+    _jtd_constructor_219_impl(name, nameOffset);
   }
-  _jtd_constructor_218_impl(String name, int nameOffset) {
+  _jtd_constructor_219_impl(String name, int nameOffset) {
   }
   accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
   ClassElement get enclosingElement => super.enclosingElement as ClassElement;
   ElementKind get kind => ElementKind.METHOD;
   String get name {
     String name = super.name;
-    if (isOperator() && name == "-") {
+    if (isOperator && name == "-") {
       if (parameters.length == 0) {
         return "unary-";
       }
     }
     return super.name;
   }
-  bool isAbstract() => hasModifier(Modifier.ABSTRACT);
-  bool isOperator() {
+  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
+  bool get isOperator {
     String name = displayName;
     if (name.isEmpty) {
       return false;
@@ -3919,11 +4013,11 @@
     int first = name.codeUnitAt(0);
     return !((0x61 <= first && first <= 0x7A) || (0x41 <= first && first <= 0x5A) || first == 0x5F || first == 0x24);
   }
-  bool isStatic() => hasModifier(Modifier.STATIC);
+  bool get 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
+   * @param isAbstract `true` if the method is abstract
    */
   void set abstract(bool isAbstract) {
     setModifier(Modifier.ABSTRACT, isAbstract);
@@ -3931,7 +4025,7 @@
 
   /**
    * Set whether this method is static to correspond to the given value.
-   * @param isStatic {@code true} if the method is static
+   * @param isStatic `true` if the method is static
    */
   void set static(bool isStatic) {
     setModifier(Modifier.STATIC, isStatic);
@@ -3944,7 +4038,7 @@
   }
 }
 /**
- * The enumeration {@code Modifier} defines constants for all of the modifiers defined by the Dart
+ * The enumeration `Modifier` defines constants for all of the modifiers defined by the Dart
  * language and for a few additional flags that are useful.
  * @coverage dart.engine.element
  */
@@ -3974,7 +4068,7 @@
   String toString() => name;
 }
 /**
- * Instances of the class {@code MultiplyDefinedElementImpl} represent a collection of elements that
+ * Instances of the class `MultiplyDefinedElementImpl` represent a collection of elements that
  * have the same name within the same scope.
  * @coverage dart.engine.element
  */
@@ -4027,7 +4121,7 @@
     }
     return false;
   }
-  bool isSynthetic() => true;
+  bool get isSynthetic => true;
   String toString() {
     JavaStringBuilder builder = new JavaStringBuilder();
     builder.append("[");
@@ -4076,7 +4170,7 @@
   }
 }
 /**
- * Instances of the class {@code ParameterElementImpl} implement a {@code ParameterElement}.
+ * Instances of the class `ParameterElementImpl` implement a `ParameterElement`.
  * @coverage dart.engine.element
  */
 class ParameterElementImpl extends VariableElementImpl implements ParameterElement {
@@ -4098,7 +4192,7 @@
   int _defaultValueRangeOffset = 0;
 
   /**
-   * The length of the default value range for this element, or {@code -1} if this element does not
+   * The length of the default value range for this element, or `-1` if this element does not
    * have a default value.
    */
   int _defaultValueRangeLength = -1;
@@ -4109,7 +4203,7 @@
   int _visibleRangeOffset = 0;
 
   /**
-   * The length of the visible range for this element, or {@code -1} if this element does not have a
+   * The length of the visible range for this element, or `-1` if this element does not have a
    * visible range.
    */
   int _visibleRangeLength = -1;
@@ -4141,13 +4235,13 @@
     }
     return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
   }
-  bool isInitializingFormal() => false;
+  bool get isInitializingFormal => false;
 
   /**
    * Set the range of the default value for this parameter to the range starting at the given offset
    * with the given length.
    * @param offset the offset to the beginning of the default value range for this element
-   * @param length the length of the default value range for this element, or {@code -1} if this
+   * @param length the length of the default value range for this element, or `-1` if this
    * element does not have a default value
    */
   void setDefaultValueRange(int offset, int length) {
@@ -4178,7 +4272,7 @@
    * Set the visible range for this element to the range starting at the given offset with the given
    * length.
    * @param offset the offset to the beginning of the visible range for this element
-   * @param length the length of the visible range for this element, or {@code -1} if this element
+   * @param length the length of the visible range for this element, or `-1` if this element
    * does not have a visible range
    */
   void setVisibleRange(int offset, int length) {
@@ -4210,7 +4304,7 @@
   }
 }
 /**
- * Instances of the class {@code PrefixElementImpl} implement a {@code PrefixElement}.
+ * Instances of the class `PrefixElementImpl` implement a `PrefixElement`.
  * @coverage dart.engine.element
  */
 class PrefixElementImpl extends ElementImpl implements PrefixElement {
@@ -4252,7 +4346,7 @@
   }
 }
 /**
- * Instances of the class {@code PropertyAccessorElementImpl} implement a{@code PropertyAccessorElement}.
+ * Instances of the class `PropertyAccessorElementImpl` implement a`PropertyAccessorElement`.
  * @coverage dart.engine.element
  */
 class PropertyAccessorElementImpl extends ExecutableElementImpl implements PropertyAccessorElement {
@@ -4272,9 +4366,9 @@
    * @param name the name of this element
    */
   PropertyAccessorElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_223_impl(name);
+    _jtd_constructor_224_impl(name);
   }
-  _jtd_constructor_223_impl(Identifier name) {
+  _jtd_constructor_224_impl(Identifier name) {
   }
 
   /**
@@ -4283,47 +4377,47 @@
    * @param variable the variable with which this access is associated
    */
   PropertyAccessorElementImpl.con2(PropertyInducingElementImpl variable2) : super.con2(variable2.name, variable2.nameOffset) {
-    _jtd_constructor_224_impl(variable2);
+    _jtd_constructor_225_impl(variable2);
   }
-  _jtd_constructor_224_impl(PropertyInducingElementImpl variable2) {
+  _jtd_constructor_225_impl(PropertyInducingElementImpl variable2) {
     this._variable = variable2;
     synthetic = true;
   }
   accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
-  bool operator ==(Object object) => super == object && identical(isGetter(), ((object as PropertyAccessorElement)).isGetter());
+  bool operator ==(Object object) => super == object && identical(isGetter, ((object as PropertyAccessorElement)).isGetter);
   PropertyAccessorElement get correspondingGetter {
-    if (isGetter() || _variable == null) {
+    if (isGetter || _variable == null) {
       return null;
     }
     return _variable.getter;
   }
   PropertyAccessorElement get correspondingSetter {
-    if (isSetter() || _variable == null) {
+    if (isSetter || _variable == null) {
       return null;
     }
     return _variable.setter;
   }
   ElementKind get kind {
-    if (isGetter()) {
+    if (isGetter) {
       return ElementKind.GETTER;
     }
     return ElementKind.SETTER;
   }
   String get name {
-    if (isSetter()) {
+    if (isSetter) {
       return "${super.name}=";
     }
     return super.name;
   }
   PropertyInducingElement get variable => _variable;
-  bool isAbstract() => hasModifier(Modifier.ABSTRACT);
-  bool isGetter() => hasModifier(Modifier.GETTER);
-  bool isSetter() => hasModifier(Modifier.SETTER);
-  bool isStatic() => hasModifier(Modifier.STATIC);
+  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
+  bool get isGetter => hasModifier(Modifier.GETTER);
+  bool get isSetter => hasModifier(Modifier.SETTER);
+  bool get isStatic => hasModifier(Modifier.STATIC);
 
   /**
    * Set whether this accessor is abstract to correspond to the given value.
-   * @param isAbstract {@code true} if the accessor is abstract
+   * @param isAbstract `true` if the accessor is abstract
    */
   void set abstract(bool isAbstract) {
     setModifier(Modifier.ABSTRACT, isAbstract);
@@ -4331,7 +4425,7 @@
 
   /**
    * Set whether this accessor is a getter to correspond to the given value.
-   * @param isGetter {@code true} if the accessor is a getter
+   * @param isGetter `true` if the accessor is a getter
    */
   void set getter(bool isGetter) {
     setModifier(Modifier.GETTER, isGetter);
@@ -4339,7 +4433,7 @@
 
   /**
    * Set whether this accessor is a setter to correspond to the given value.
-   * @param isSetter {@code true} if the accessor is a setter
+   * @param isSetter `true` if the accessor is a setter
    */
   void set setter(bool isSetter) {
     setModifier(Modifier.SETTER, isSetter);
@@ -4347,7 +4441,7 @@
 
   /**
    * Set whether this accessor is static to correspond to the given value.
-   * @param isStatic {@code true} if the accessor is static
+   * @param isStatic `true` if the accessor is static
    */
   void set static(bool isStatic) {
     setModifier(Modifier.STATIC, isStatic);
@@ -4361,13 +4455,13 @@
     this._variable = variable2;
   }
   void appendTo(JavaStringBuilder builder) {
-    builder.append(isGetter() ? "get " : "set ");
+    builder.append(isGetter ? "get " : "set ");
     builder.append(variable.displayName);
     super.appendTo(builder);
   }
 }
 /**
- * Instances of the class {@code PropertyInducingElementImpl} implement a{@code PropertyInducingElement}.
+ * Instances of the class `PropertyInducingElementImpl` implement a`PropertyInducingElement`.
  * @coverage dart.engine.element
  */
 abstract class PropertyInducingElementImpl extends VariableElementImpl implements PropertyInducingElement {
@@ -4378,7 +4472,7 @@
   PropertyAccessorElement _getter;
 
   /**
-   * The setter associated with this element, or {@code null} if the element is effectively{@code final} and therefore does not have a setter associated with it.
+   * The setter associated with this element, or `null` if the element is effectively`final` and therefore does not have a setter associated with it.
    */
   PropertyAccessorElement _setter;
 
@@ -4392,9 +4486,9 @@
    * @param name the name of this element
    */
   PropertyInducingElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_225_impl(name);
+    _jtd_constructor_226_impl(name);
   }
-  _jtd_constructor_225_impl(Identifier name) {
+  _jtd_constructor_226_impl(Identifier name) {
   }
 
   /**
@@ -4402,9 +4496,9 @@
    * @param name the name of this element
    */
   PropertyInducingElementImpl.con2(String name) : super.con2(name, -1) {
-    _jtd_constructor_226_impl(name);
+    _jtd_constructor_227_impl(name);
   }
-  _jtd_constructor_226_impl(String name) {
+  _jtd_constructor_227_impl(String name) {
     synthetic = true;
   }
   PropertyAccessorElement get getter => _getter;
@@ -4427,7 +4521,7 @@
   }
 }
 /**
- * Instances of the class {@code ShowElementCombinatorImpl} implement a{@link ShowElementCombinator}.
+ * Instances of the class `ShowElementCombinatorImpl` implement a[ShowElementCombinator].
  * @coverage dart.engine.element
  */
 class ShowElementCombinatorImpl implements ShowElementCombinator {
@@ -4461,7 +4555,7 @@
   }
 }
 /**
- * Instances of the class {@code TopLevelVariableElementImpl} implement a{@code TopLevelVariableElement}.
+ * Instances of the class `TopLevelVariableElementImpl` implement a`TopLevelVariableElement`.
  * @coverage dart.engine.element
  */
 class TopLevelVariableElementImpl extends PropertyInducingElementImpl implements TopLevelVariableElement {
@@ -4476,9 +4570,9 @@
    * @param name the name of this element
    */
   TopLevelVariableElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_228_impl(name);
+    _jtd_constructor_229_impl(name);
   }
-  _jtd_constructor_228_impl(Identifier name) {
+  _jtd_constructor_229_impl(Identifier name) {
   }
 
   /**
@@ -4486,16 +4580,16 @@
    * @param name the name of this element
    */
   TopLevelVariableElementImpl.con2(String name) : super.con2(name) {
-    _jtd_constructor_229_impl(name);
+    _jtd_constructor_230_impl(name);
   }
-  _jtd_constructor_229_impl(String name) {
+  _jtd_constructor_230_impl(String name) {
   }
   accept(ElementVisitor visitor) => visitor.visitTopLevelVariableElement(this);
   ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
-  bool isStatic() => true;
+  bool get isStatic => true;
 }
 /**
- * Instances of the class {@code TypeVariableElementImpl} implement a {@code TypeVariableElement}.
+ * Instances of the class `TypeVariableElementImpl` implement a `TypeVariableElement`.
  * @coverage dart.engine.element
  */
 class TypeVariableElementImpl extends ElementImpl implements TypeVariableElement {
@@ -4506,7 +4600,7 @@
   TypeVariableType _type;
 
   /**
-   * The type representing the bound associated with this variable, or {@code null} if this variable
+   * The type representing the bound associated with this variable, or `null` if this variable
    * does not have an explicit bound.
    */
   Type2 _bound;
@@ -4551,7 +4645,7 @@
   }
 }
 /**
- * Instances of the class {@code VariableElementImpl} implement a {@code VariableElement}.
+ * Instances of the class `VariableElementImpl` implement a `VariableElement`.
  * @coverage dart.engine.element
  */
 abstract class VariableElementImpl extends ElementImpl implements VariableElement {
@@ -4562,7 +4656,7 @@
   Type2 _type;
 
   /**
-   * A synthetic function representing this variable's initializer, or {@code null} if this variable
+   * A synthetic function representing this variable's initializer, or `null` if this variable
    * does not have an initializer.
    */
   FunctionElement _initializer;
@@ -4577,9 +4671,9 @@
    * @param name the name of this element
    */
   VariableElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_231_impl(name);
+    _jtd_constructor_232_impl(name);
   }
-  _jtd_constructor_231_impl(Identifier name) {
+  _jtd_constructor_232_impl(Identifier name) {
   }
 
   /**
@@ -4589,26 +4683,26 @@
    * declaration of this element
    */
   VariableElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset) {
-    _jtd_constructor_232_impl(name, nameOffset);
+    _jtd_constructor_233_impl(name, nameOffset);
   }
-  _jtd_constructor_232_impl(String name, int nameOffset) {
+  _jtd_constructor_233_impl(String name, int nameOffset) {
   }
 
   /**
    * Return the result of evaluating this variable's initializer as a compile-time constant
-   * expression, or {@code null} if this variable is not a 'const' variable or does not have an
+   * expression, or `null` if this variable is not a 'const' variable or does not have an
    * initializer.
    * @return the result of evaluating this variable's initializer
    */
   EvaluationResultImpl get evaluationResult => null;
   FunctionElement get initializer => _initializer;
   Type2 get type => _type;
-  bool isConst() => hasModifier(Modifier.CONST);
-  bool isFinal() => hasModifier(Modifier.FINAL);
+  bool get isConst => hasModifier(Modifier.CONST);
+  bool get 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
+   * @param isConst `true` if the variable is const
    */
   void set const3(bool isConst) {
     setModifier(Modifier.CONST, isConst);
@@ -4625,7 +4719,7 @@
 
   /**
    * Set whether this variable is final to correspond to the given value.
-   * @param isFinal {@code true} if the variable is final
+   * @param isFinal `true` if the variable is final
    */
   void set final2(bool isFinal) {
     setModifier(Modifier.FINAL, isFinal);
@@ -4660,7 +4754,7 @@
   }
 }
 /**
- * Instances of the class {@code ConstructorMember} represent a constructor element defined in a
+ * Instances of the class `ConstructorMember` represent a constructor element defined in a
  * parameterized type where the values of the type parameters are known.
  */
 class ConstructorMember extends ExecutableMember implements ConstructorElement {
@@ -4681,7 +4775,7 @@
     }
     FunctionType baseType = baseConstructor.type;
     List<Type2> argumentTypes = definingType.typeArguments;
-    List<Type2> parameterTypes = TypeVariableTypeImpl.getTypes(definingType.element.typeVariables);
+    List<Type2> parameterTypes = definingType.element.type.typeArguments;
     FunctionType substitutedType = baseType.substitute2(argumentTypes, parameterTypes);
     if (baseType == substitutedType) {
       return baseConstructor;
@@ -4700,8 +4794,9 @@
   ConstructorElement get baseElement => super.baseElement as ConstructorElement;
   ClassElement get enclosingElement => baseElement.enclosingElement;
   ConstructorElement get redirectedConstructor => from(baseElement.redirectedConstructor, definingType);
-  bool isConst() => baseElement.isConst();
-  bool isFactory() => baseElement.isFactory();
+  bool get isConst => baseElement.isConst;
+  bool get isDefaultConstructor => baseElement.isDefaultConstructor;
+  bool get isFactory => baseElement.isFactory;
   String toString() {
     ConstructorElement baseElement = this.baseElement;
     List<ParameterElement> parameters = this.parameters;
@@ -4731,7 +4826,7 @@
   InterfaceType get definingType => super.definingType as InterfaceType;
 }
 /**
- * The abstract class {@code ExecutableMember} defines the behavior common to members that represent
+ * The abstract class `ExecutableMember` defines the behavior common to members that represent
  * an executable element defined in a parameterized type where the values of the type parameters are
  * known.
  */
@@ -4765,9 +4860,10 @@
     }
     return parameterizedParameters;
   }
+  Type2 get returnType => substituteFor(baseElement.returnType);
   FunctionType get type => substituteFor(baseElement.type);
-  bool isOperator() => baseElement.isOperator();
-  bool isStatic() => baseElement.isStatic();
+  bool get isOperator => baseElement.isOperator;
+  bool get isStatic => baseElement.isStatic;
   void visitChildren(ElementVisitor<Object> visitor) {
     super.visitChildren(visitor);
     safelyVisitChildren(baseElement.functions, visitor);
@@ -4777,7 +4873,7 @@
   }
 }
 /**
- * Instances of the class {@code FieldMember} represent a field element defined in a parameterized
+ * Instances of the class `FieldMember` represent a field element defined in a parameterized
  * type where the values of the type parameters are known.
  */
 class FieldMember extends VariableMember implements FieldElement {
@@ -4801,7 +4897,7 @@
       return baseField;
     }
     List<Type2> argumentTypes = definingType.typeArguments;
-    List<Type2> parameterTypes = TypeVariableTypeImpl.getTypes(definingType.element.typeVariables);
+    List<Type2> parameterTypes = definingType.element.type.typeArguments;
     Type2 substitutedType = baseType.substitute2(argumentTypes, parameterTypes);
     if (baseType == substitutedType) {
       return baseField;
@@ -4821,11 +4917,11 @@
   ClassElement get enclosingElement => baseElement.enclosingElement;
   PropertyAccessorElement get getter => PropertyAccessorMember.from(baseElement.getter, definingType);
   PropertyAccessorElement get setter => PropertyAccessorMember.from(baseElement.setter, definingType);
-  bool isStatic() => baseElement.isStatic();
+  bool get isStatic => baseElement.isStatic;
   InterfaceType get definingType => super.definingType as InterfaceType;
 }
 /**
- * The abstract class {@code Member} defines the behavior common to elements that represent members
+ * The abstract class `Member` defines the behavior common to elements that represent members
  * of parameterized types.
  */
 abstract class Member implements Element {
@@ -4867,7 +4963,7 @@
   int get nameOffset => _baseElement.nameOffset;
   Source get source => _baseElement.source;
   bool isAccessibleIn(LibraryElement library) => _baseElement.isAccessibleIn(library);
-  bool isSynthetic() => _baseElement.isSynthetic();
+  bool get isSynthetic => _baseElement.isSynthetic;
   void visitChildren(ElementVisitor<Object> visitor) {
   }
 
@@ -4878,7 +4974,7 @@
   ParameterizedType get definingType => _definingType;
 
   /**
-   * If the given child is not {@code null}, use the given visitor to visit it.
+   * If the given child is not `null`, use the given visitor to visit it.
    * @param child the child to be visited
    * @param visitor the visitor to be used to visit the child
    */
@@ -4929,7 +5025,7 @@
   }
 }
 /**
- * Instances of the class {@code MethodMember} represent a method element defined in a parameterized
+ * Instances of the class `MethodMember` represent a method element defined in a parameterized
  * type where the values of the type parameters are known.
  */
 class MethodMember extends ExecutableMember implements MethodElement {
@@ -4950,7 +5046,7 @@
     }
     FunctionType baseType = baseMethod.type;
     List<Type2> argumentTypes = definingType.typeArguments;
-    List<Type2> parameterTypes = TypeVariableTypeImpl.getTypes(definingType.element.typeVariables);
+    List<Type2> parameterTypes = definingType.element.type.typeArguments;
     FunctionType substitutedType = baseType.substitute2(argumentTypes, parameterTypes);
     if (baseType == substitutedType) {
       return baseMethod;
@@ -4968,7 +5064,7 @@
   accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
   MethodElement get baseElement => super.baseElement as MethodElement;
   ClassElement get enclosingElement => baseElement.enclosingElement;
-  bool isAbstract() => baseElement.isAbstract();
+  bool get isAbstract => baseElement.isAbstract;
   String toString() {
     MethodElement baseElement = this.baseElement;
     List<ParameterElement> parameters = this.parameters;
@@ -4994,7 +5090,7 @@
   }
 }
 /**
- * Instances of the class {@code ParameterMember} represent a parameter element defined in a
+ * Instances of the class `ParameterMember` represent a parameter element defined in a
  * parameterized type where the values of the type parameters are known.
  */
 class ParameterMember extends VariableMember implements ParameterElement {
@@ -5063,7 +5159,7 @@
     return parameterizedParameters;
   }
   SourceRange get visibleRange => baseElement.visibleRange;
-  bool isInitializingFormal() => baseElement.isInitializingFormal();
+  bool get isInitializingFormal => baseElement.isInitializingFormal;
   String toString() {
     ParameterElement baseElement = this.baseElement;
     String left = "";
@@ -5092,7 +5188,7 @@
   }
 }
 /**
- * Instances of the class {@code PropertyAccessorMember} represent a property accessor element
+ * Instances of the class `PropertyAccessorMember` represent a property accessor element
  * defined in a parameterized type where the values of the type parameters are known.
  */
 class PropertyAccessorMember extends ExecutableMember implements PropertyAccessorElement {
@@ -5113,7 +5209,7 @@
     }
     FunctionType baseType = baseAccessor.type;
     List<Type2> argumentTypes = definingType.typeArguments;
-    List<Type2> parameterTypes = TypeVariableTypeImpl.getTypes(definingType.element.typeVariables);
+    List<Type2> parameterTypes = definingType.element.type.typeArguments;
     FunctionType substitutedType = baseType.substitute2(argumentTypes, parameterTypes);
     if (baseType == substitutedType) {
       return baseAccessor;
@@ -5141,13 +5237,13 @@
     }
     return variable;
   }
-  bool isAbstract() => baseElement.isAbstract();
-  bool isGetter() => baseElement.isGetter();
-  bool isSetter() => baseElement.isSetter();
+  bool get isAbstract => baseElement.isAbstract;
+  bool get isGetter => baseElement.isGetter;
+  bool get isSetter => baseElement.isSetter;
   InterfaceType get definingType => super.definingType as InterfaceType;
 }
 /**
- * The abstract class {@code VariableMember} defines the behavior common to members that represent a
+ * The abstract class `VariableMember` defines the behavior common to members that represent a
  * variable element defined in a parameterized type where the values of the type parameters are
  * known.
  */
@@ -5166,38 +5262,15 @@
     throw new UnsupportedOperationException();
   }
   Type2 get type => substituteFor(baseElement.type);
-  bool isConst() => baseElement.isConst();
-  bool isFinal() => baseElement.isFinal();
+  bool get isConst => baseElement.isConst;
+  bool get isFinal => baseElement.isFinal;
   void visitChildren(ElementVisitor<Object> visitor) {
     super.visitChildren(visitor);
     safelyVisitChild(baseElement.initializer, visitor);
   }
 }
 /**
- * Instances of the class {@code AnonymousFunctionTypeImpl} extend the behavior of{@link FunctionTypeImpl} to support anonymous function types created for function typed
- * parameters.
- * @coverage dart.engine.type
- */
-class AnonymousFunctionTypeImpl extends FunctionTypeImpl {
-
-  /**
-   * An array of parameters elements of this type of function.
-   */
-  List<ParameterElement> _baseParameters = ParameterElementImpl.EMPTY_ARRAY;
-  AnonymousFunctionTypeImpl() : super.con2((null as FunctionTypeAliasElement)) {
-  }
-
-  /**
-   * Sets the parameters elements of this type of function.
-   * @param parameters the parameters elements of this type of function
-   */
-  void set baseParameters(List<ParameterElement> parameters) {
-    this._baseParameters = parameters;
-  }
-  List<ParameterElement> get baseParameters => _baseParameters;
-}
-/**
- * The unique instance of the class {@code BottomTypeImpl} implements the type {@code bottom}.
+ * The unique instance of the class `BottomTypeImpl` implements the type `bottom`.
  * @coverage dart.engine.type
  */
 class BottomTypeImpl extends TypeImpl {
@@ -5225,7 +5298,7 @@
   BottomTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) => this;
 }
 /**
- * The unique instance of the class {@code DynamicTypeImpl} implements the type {@code dynamic}.
+ * The unique instance of the class `DynamicTypeImpl` implements the type `dynamic`.
  * @coverage dart.engine.type
  */
 class DynamicTypeImpl extends TypeImpl {
@@ -5248,26 +5321,26 @@
     ((element as DynamicElementImpl)).type = this;
   }
   bool operator ==(Object object) => object is DynamicTypeImpl;
-  bool isDynamic() => true;
+  bool get isDynamic => true;
   bool isMoreSpecificThan(Type2 type) => false;
   bool isSubtypeOf(Type2 type) => identical(this, type);
   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
+ * Instances of the class `FunctionTypeImpl` defines the behavior common to objects
  * representing the type of a function, method, constructor, getter, or setter.
  * @coverage dart.engine.type
  */
 class FunctionTypeImpl extends TypeImpl implements FunctionType {
 
   /**
-   * Return {@code true} if all of the name/type pairs in the first map are equal to the
+   * Return `true` if all of the name/type pairs in the first map are equal to the
    * corresponding name/type pairs in the second map. The maps are expected to iterate over their
    * entries in the same order in which those entries were added to the map.
    * @param firstTypes the first map of name/type pairs being compared
    * @param secondTypes the second map of name/type pairs being compared
-   * @return {@code true} if all of the name/type pairs in the first map are equal to the
+   * @return `true` if all of the name/type pairs in the first map are equal to the
    * corresponding name/type pairs in the second map
    */
   static bool equals2(Map<String, Type2> firstTypes, Map<String, Type2> secondTypes) {
@@ -5331,11 +5404,6 @@
   Map<String, Type2> _namedParameterTypes = new Map();
 
   /**
-   * 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
@@ -5361,11 +5429,12 @@
       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) && _returnType == otherType._returnType;
+    return element == otherType.element && JavaArrays.equals(_normalParameterTypes, otherType._normalParameterTypes) && JavaArrays.equals(_optionalParameterTypes, otherType._optionalParameterTypes) && equals2(_namedParameterTypes, otherType._namedParameterTypes) && returnType == otherType.returnType;
   }
   String get displayName {
     String name = this.name;
     if (name == null) {
+      Type2 returnType = this.returnType;
       JavaStringBuilder builder = new JavaStringBuilder();
       builder.append("(");
       bool needsComma = false;
@@ -5416,10 +5485,10 @@
         needsComma = true;
       }
       builder.append(") -> ");
-      if (_returnType == null) {
+      if (returnType == null) {
         builder.append("null");
       } else {
-        builder.append(_returnType.displayName);
+        builder.append(returnType.displayName);
       }
       name = builder.toString();
     }
@@ -5440,13 +5509,20 @@
     }
     return specializedParameters;
   }
-  Type2 get returnType => _returnType;
+  Type2 get returnType {
+    Type2 baseReturnType = this.baseReturnType;
+    return baseReturnType.substitute2(_typeArguments, TypeVariableTypeImpl.getTypes(typeVariables));
+  }
   List<Type2> get typeArguments => _typeArguments;
   List<TypeVariableElement> get typeVariables {
     Element element = this.element;
     if (element is FunctionTypeAliasElement) {
       return ((element as FunctionTypeAliasElement)).typeVariables;
     }
+    ClassElement definingClass = element.getAncestor(ClassElement);
+    if (definingClass != null) {
+      return definingClass.typeVariables;
+    }
     return TypeVariableElementImpl.EMPTY_ARRAY;
   }
   int get hashCode {
@@ -5459,7 +5535,7 @@
   bool isSubtypeOf(Type2 type) {
     if (type == null) {
       return false;
-    } else if (identical(this, type) || type.isDynamic() || type.isDartCoreFunction() || type.isObject()) {
+    } else if (identical(this, type) || type.isDynamic || type.isDartCoreFunction || type.isObject) {
       return true;
     } else if (type is! FunctionType) {
       return false;
@@ -5561,14 +5637,6 @@
   }
 
   /**
-   * 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 returnType(Type2 returnType2) {
-    this._returnType = returnType2;
-  }
-
-  /**
    * Set the actual types of the type arguments to the given types.
    * @param typeArguments the actual types of the type arguments
    */
@@ -5585,14 +5653,14 @@
     }
     Element element = this.element;
     FunctionTypeImpl newType = (element is ExecutableElement) ? new FunctionTypeImpl.con1((element as ExecutableElement)) : new FunctionTypeImpl.con2((element as FunctionTypeAliasElement));
-    newType.returnType = _returnType.substitute2(argumentTypes, parameterTypes);
     newType.normalParameterTypes = TypeImpl.substitute(_normalParameterTypes, argumentTypes, parameterTypes);
     newType.optionalParameterTypes = TypeImpl.substitute(_optionalParameterTypes, argumentTypes, parameterTypes);
     newType._namedParameterTypes = substitute3(_namedParameterTypes, argumentTypes, parameterTypes);
-    newType.typeArguments = argumentTypes;
+    newType.typeArguments = TypeImpl.substitute(_typeArguments, argumentTypes, parameterTypes);
     return newType;
   }
   void appendTo(JavaStringBuilder builder) {
+    Type2 returnType = this.returnType;
     builder.append("(");
     bool needsComma = false;
     if (_normalParameterTypes.length > 0) {
@@ -5642,15 +5710,15 @@
       needsComma = true;
     }
     builder.append(") -> ");
-    if (_returnType == null) {
+    if (returnType == null) {
       builder.append("null");
     } else {
-      ((_returnType as TypeImpl)).appendTo(builder);
+      ((returnType as TypeImpl)).appendTo(builder);
     }
   }
 
   /**
-   * @return the base parameter elements of this function element, not {@code null}.
+   * @return the base parameter elements of this function element, not `null`.
    */
   List<ParameterElement> get baseParameters {
     Element element = this.element;
@@ -5660,9 +5728,22 @@
       return ((element as FunctionTypeAliasElement)).parameters;
     }
   }
+
+  /**
+   * Return the return type defined by this function's element.
+   * @return the return type defined by this function's element
+   */
+  Type2 get baseReturnType {
+    Element element = this.element;
+    if (element is ExecutableElement) {
+      return ((element as ExecutableElement)).returnType;
+    } else {
+      return ((element as FunctionTypeAliasElement)).returnType;
+    }
+  }
 }
 /**
- * Instances of the class {@code InterfaceTypeImpl} defines the behavior common to objects
+ * Instances of the class `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.
  * @coverage dart.engine.type
@@ -5675,25 +5756,25 @@
   static List<InterfaceType> EMPTY_ARRAY = new List<InterfaceType>(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
+   * This method computes the longest inheritance path from some passed [Type] to Object.
+   * @param type the [Type] to compute the longest inheritance path of from the passed[Type] to Object
    * @return the computed longest inheritance path to Object
    * @see InterfaceType#getLeastUpperBound(Type)
    */
   static int computeLongestInheritancePathToObject(InterfaceType type) => computeLongestInheritancePathToObject2(type, 0, new Set<ClassElement>());
 
   /**
-   * 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}
+   * Returns the set of all superinterfaces of the passed [Type].
+   * @param type the [Type] to compute the set of superinterfaces of
+   * @return the [Set] of superinterfaces of the passed [Type]
    * @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
+   * This method computes the longest inheritance path from some passed [Type] to Object. This
+   * method calls itself recursively, callers should use the public method[computeLongestInheritancePathToObject].
+   * @param type the [Type] to compute the longest inheritance path of from the passed[Type] to Object
    * @param depth a field used recursively
    * @param visitedClasses the classes that have already been visited
    * @return the computed longest inheritance path to Object
@@ -5730,11 +5811,11 @@
   }
 
   /**
-   * 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}
+   * Returns the set of all superinterfaces of the passed [Type]. This is a recursive method,
+   * callers should call the public [computeSuperinterfaceSet].
+   * @param type the [Type] to compute the set of superinterfaces of
+   * @param set a [HashSet] used recursively by this method
+   * @return the [Set] of superinterfaces of the passed [Type]
    * @see #computeSuperinterfaceSet(Type)
    * @see #getLeastUpperBound(Type)
    */
@@ -5848,19 +5929,28 @@
     InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
     return element == otherType.element && JavaArrays.equals(_typeArguments, otherType._typeArguments);
   }
+  List<PropertyAccessorElement> get accessors {
+    List<PropertyAccessorElement> accessors = element.accessors;
+    List<PropertyAccessorElement> members = new List<PropertyAccessorElement>(accessors.length);
+    for (int i = 0; i < accessors.length; i++) {
+      members[i] = PropertyAccessorMember.from(accessors[i], this);
+    }
+    return members;
+  }
   ClassElement get element => super.element as ClassElement;
   PropertyAccessorElement getGetter(String getterName) => PropertyAccessorMember.from(((element as ClassElementImpl)).getGetter(getterName), this);
   List<InterfaceType> get interfaces {
     ClassElement classElement = element;
     List<InterfaceType> interfaces = classElement.interfaces;
     List<TypeVariableElement> typeVariables = classElement.typeVariables;
+    List<Type2> parameterTypes = classElement.type.typeArguments;
     if (typeVariables.length == 0) {
       return interfaces;
     }
     int count = interfaces.length;
     List<InterfaceType> typedInterfaces = new List<InterfaceType>(count);
     for (int i = 0; i < count; i++) {
-      typedInterfaces[i] = interfaces[i].substitute2(_typeArguments, TypeVariableTypeImpl.getTypes(typeVariables));
+      typedInterfaces[i] = interfaces[i].substitute2(_typeArguments, parameterTypes);
     }
     return typedInterfaces;
   }
@@ -5906,17 +5996,26 @@
     return null;
   }
   MethodElement getMethod(String methodName) => MethodMember.from(((element as ClassElementImpl)).getMethod(methodName), this);
+  List<MethodElement> get methods {
+    List<MethodElement> methods = element.methods;
+    List<MethodElement> members = new List<MethodElement>(methods.length);
+    for (int i = 0; i < methods.length; i++) {
+      members[i] = MethodMember.from(methods[i], this);
+    }
+    return members;
+  }
   List<InterfaceType> get mixins {
     ClassElement classElement = element;
     List<InterfaceType> mixins = classElement.mixins;
     List<TypeVariableElement> typeVariables = classElement.typeVariables;
+    List<Type2> parameterTypes = classElement.type.typeArguments;
     if (typeVariables.length == 0) {
       return mixins;
     }
     int count = mixins.length;
     List<InterfaceType> typedMixins = new List<InterfaceType>(count);
     for (int i = 0; i < count; i++) {
-      typedMixins[i] = mixins[i].substitute2(_typeArguments, TypeVariableTypeImpl.getTypes(typeVariables));
+      typedMixins[i] = mixins[i].substitute2(_typeArguments, parameterTypes);
     }
     return typedMixins;
   }
@@ -5927,7 +6026,7 @@
     if (supertype == null) {
       return null;
     }
-    return supertype.substitute2(_typeArguments, TypeVariableTypeImpl.getTypes(classElement.typeVariables));
+    return supertype.substitute2(_typeArguments, classElement.type.typeArguments);
   }
   List<Type2> get typeArguments => _typeArguments;
   List<TypeVariableElement> get typeVariables => element.typeVariables;
@@ -5938,12 +6037,12 @@
     }
     return element.hashCode;
   }
-  bool isDartCoreFunction() {
+  bool get isDartCoreFunction {
     ClassElement element = this.element;
     if (element == null) {
       return false;
     }
-    return element.name == "Function" && element.library.isDartCore();
+    return element.name == "Function" && element.library.isDartCore;
   }
   bool isDirectSupertypeOf(InterfaceType type) {
     ClassElement i = element;
@@ -5976,7 +6075,7 @@
     }
     return isMoreSpecificThan2((type as InterfaceType), new Set<ClassElement>());
   }
-  bool isObject() => element.supertype == null;
+  bool get isObject => element.supertype == null;
   bool isSubtypeOf(Type2 type2) {
     if (identical(type2, DynamicTypeImpl.instance)) {
       return true;
@@ -6187,15 +6286,15 @@
     }
     return false;
   }
-  bool isSubtypeOf2(InterfaceType type, Set<ClassElement> visitedClasses) {
+  bool isSubtypeOf2(InterfaceType type2, Set<ClassElement> visitedClasses) {
     InterfaceType typeT = this;
-    InterfaceType typeS = type;
+    InterfaceType typeS = type2;
     ClassElement elementT = element;
     if (elementT == null || visitedClasses.contains(elementT)) {
       return false;
     }
     javaSetAdd(visitedClasses, elementT);
-    typeT = substitute2(_typeArguments, TypeVariableTypeImpl.getTypes(elementT.typeVariables));
+    typeT = substitute2(_typeArguments, elementT.type.typeArguments);
     if (typeT == typeS) {
       return true;
     } else if (elementT == typeS.element) {
@@ -6210,7 +6309,7 @@
         }
       }
       return true;
-    } else if (typeS.isDartCoreFunction() && elementT.getMethod("call") != null) {
+    } else if (typeS.isDartCoreFunction && elementT.getMethod("call") != null) {
       return true;
     }
     InterfaceType supertype = elementT.supertype;
@@ -6233,7 +6332,7 @@
   }
 }
 /**
- * The abstract class {@code TypeImpl} implements the behavior common to objects representing the
+ * The abstract class `TypeImpl` implements the behavior common to objects representing the
  * declared type of elements in the element model.
  * @coverage dart.engine.type
  */
@@ -6260,13 +6359,13 @@
   }
 
   /**
-   * The element representing the declaration of this type, or {@code null} if the type has not, or
+   * The element representing the declaration of this type, or `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.
+   * The name of this type, or `null` if the type does not have a name.
    */
   String _name;
 
@@ -6289,12 +6388,12 @@
   Type2 getLeastUpperBound(Type2 type) => null;
   String get name => _name;
   bool isAssignableTo(Type2 type) => this.isSubtypeOf(type) || type.isSubtypeOf(this);
-  bool isDartCoreFunction() => false;
-  bool isDynamic() => false;
+  bool get isDartCoreFunction => false;
+  bool get isDynamic => false;
   bool isMoreSpecificThan(Type2 type) => false;
-  bool isObject() => false;
+  bool get isObject => false;
   bool isSupertypeOf(Type2 type) => type.isSubtypeOf(this);
-  bool isVoid() => false;
+  bool get isVoid => false;
   String toString() {
     JavaStringBuilder builder = new JavaStringBuilder();
     appendTo(builder);
@@ -6314,13 +6413,18 @@
   }
 }
 /**
- * Instances of the class {@code TypeVariableTypeImpl} defines the behavior of objects representing
+ * Instances of the class `TypeVariableTypeImpl` defines the behavior of objects representing
  * the type introduced by a type variable.
  * @coverage dart.engine.type
  */
 class TypeVariableTypeImpl extends TypeImpl implements TypeVariableType {
 
   /**
+   * An empty array of type variable types.
+   */
+  static List<TypeVariableType> EMPTY_ARRAY = new List<TypeVariableType>(0);
+
+  /**
    * 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
@@ -6328,6 +6432,9 @@
    */
   static List<TypeVariableType> getTypes(List<TypeVariableElement> typeVariables) {
     int count = typeVariables.length;
+    if (count == 0) {
+      return EMPTY_ARRAY;
+    }
     List<TypeVariableType> types = new List<TypeVariableType>(count);
     for (int i = 0; i < count; i++) {
       types[i] = typeVariables[i].type;
@@ -6361,7 +6468,7 @@
   }
 }
 /**
- * The unique instance of the class {@code VoidTypeImpl} implements the type {@code void}.
+ * The unique instance of the class `VoidTypeImpl` implements the type `void`.
  * @coverage dart.engine.type
  */
 class VoidTypeImpl extends TypeImpl implements VoidType {
@@ -6384,20 +6491,20 @@
   }
   bool operator ==(Object object) => identical(object, this);
   bool isSubtypeOf(Type2 type) => identical(type, this) || identical(type, DynamicTypeImpl.instance);
-  bool isVoid() => true;
+  bool get isVoid => true;
   VoidTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) => this;
 }
 /**
- * The interface {@code FunctionType} defines the behavior common to objects representing the type
+ * The interface `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
+ * * 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>.
+ * * 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 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>
+ * T</i>.
+ * * The types of functions with named 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>.
  * </ol>
  * @coverage dart.engine.type
  */
@@ -6442,53 +6549,53 @@
   Type2 get returnType;
 
   /**
-   * Return {@code true} if this type is a subtype of the given type.
-   * <p>
+   * Return `true` if this type is a subtype of the given type.
+   *
    * 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>
+   *
+   * * Either
+   *
+   * * <i>S</i> is void, or
+   * * <i>T &hArr; S</i>.
+   *
+   *
+   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr; S<sub>i</sub></i>.
+   *
    * 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>
+   *
+   * * Either
+   *
+   * * <i>S</i> is void, or
+   * * <i>T &hArr; S</i>.
+   *
+   *
+   * * <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>.
+   *
    * 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>
+   *
+   * * Either
+   *
+   * * <i>S</i> is void,
+   * * or <i>T &hArr; S</i>.
+   *
+   *
+   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr; S<sub>i</sub></i>.
+   * * <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>.
+   * * 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>.
+   *
    * 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;,
@@ -6497,18 +6604,18 @@
    * 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
+   *
+   * All functions implement the class `Function`. However not all function types are a
+   * subtype of `Function`. If an interface type <i>I</i> includes a method named`call()`, and the type of `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
+   * @return `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())}.
+   * This is fully equivalent to `substitute(argumentTypes, getTypeArguments())`.
    * @param argumentTypes the actual type arguments being substituted for the type parameters
    * @return the result of performing the substitution
    */
@@ -6516,16 +6623,22 @@
   FunctionType substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes);
 }
 /**
- * The interface {@code InterfaceType} defines the behavior common to objects representing the type
+ * The interface `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.
  * @coverage dart.engine.type
  */
 abstract class InterfaceType implements ParameterizedType {
+
+  /**
+   * Return an array containing all of the accessors (getters and setters) declared in this type.
+   * @return the accessors declared in this type
+   */
+  List<PropertyAccessorElement> get accessors;
   ClassElement get element;
 
   /**
    * Return the element representing the getter with the given name that is declared in this class,
-   * or {@code null} if this class does not declare a getter with the given name.
+   * or `null` if this class does not declare a getter with the given name.
    * @param getterName the name of the getter to be returned
    * @return the getter declared in this class with the given name
    */
@@ -6540,9 +6653,9 @@
   List<InterfaceType> get interfaces;
 
   /**
-   * Return the least upper bound of this type and the given type, or {@code null} if there is no
+   * Return the least upper bound of this type and the given type, or `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
@@ -6558,13 +6671,19 @@
 
   /**
    * Return the element representing the method with the given name that is declared in this class,
-   * or {@code null} if this class does not declare a method with the given name.
+   * or `null` if this class does not declare a method with the given name.
    * @param methodName the name of the method to be returned
    * @return the method declared in this class with the given name
    */
   MethodElement getMethod(String methodName);
 
   /**
+   * Return an array containing all of the methods declared in this type.
+   * @return the methods declared in this type
+   */
+  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. Note that this is <b>not</b>, in general,
    * equivalent to getting the mixins from this type's element because the types returned by this
@@ -6575,7 +6694,7 @@
 
   /**
    * Return the element representing the setter with the given name that is declared in this class,
-   * or {@code null} if this class does not declare a setter with the given name.
+   * or `null` if this class does not declare a setter with the given name.
    * @param setterName the name of the setter to be returned
    * @return the setter declared in this class with the given name
    */
@@ -6591,55 +6710,55 @@
   InterfaceType get superclass;
 
   /**
-   * Return {@code true} if this type is a direct supertype of the given type. The implicit
+   * Return `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>
+   *
+   * * <i>I</i> is Object, and <i>J</i> has no extends clause.
+   * * <i>I</i> is listed in the extends clause of <i>J</i>.
+   * * <i>I</i> is listed in the implements clause of <i>J</i>.
+   * * <i>I</i> is listed in the with clause of <i>J</i>.
+   * * <i>J</i> is a mixin application of the mixin of <i>I</i>.
+   *
    * @param type the type being compared with this type
-   * @return {@code true} if this type is a direct supertype of the given type
+   * @return `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
+   * Return `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>
+   *
+   * * Reflexivity: <i>T</i> is <i>S</i>.
+   * * <i>T</i> is bottom.
+   * * <i>S</i> is dynamic.
+   * * Direct supertype: <i>S</i> is a direct supertype of <i>T</i>.
+   * * <i>T</i> is a type variable and <i>S</i> is the upper bound of <i>T</i>.
+   * * 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>
+   * * Transitivity: <i>T &laquo; U</i> and <i>U &laquo; S</i>.
+   *
    * @param type the type being compared with this type
-   * @return {@code true} if this type is more specific than the given type
+   * @return `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
+   * Return `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
+   * @return `true` if this type is a subtype of the given type
    */
   bool isSubtypeOf(Type2 type);
 
   /**
    * Return the element representing the constructor that results from looking up the given
-   * constructor in this class with respect to the given library, or {@code null} if the look up
+   * constructor in this class with respect to the given library, or `null` if the look up
    * fails. The behavior of this method is defined by the Dart Language Specification in section
    * 12.11.1: <blockquote>If <i>e</i> is of the form <b>new</b> <i>T.id()</i> then let <i>q<i> be
    * the constructor <i>T.id</i>, otherwise let <i>q<i> be the constructor <i>T<i>. Otherwise, if
@@ -6653,17 +6772,17 @@
 
   /**
    * Return the element representing the getter that results from looking up the given getter in
-   * this class with respect to the given library, or {@code null} if the look up fails. The
+   * this class with respect to the given library, or `null` if the look up fails. The
    * behavior of this method is defined by the Dart Language Specification in section 12.15.1:
    * <blockquote>The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
    * with respect to library <i>L</i> is:
-   * <ul>
-   * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
+   *
+   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
    * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
    * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
    * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.</li>
-   * </ul>
+   * Otherwise, we say that the lookup has failed.
+   *
    * </blockquote>
    * @param getterName the name of the getter being looked up
    * @param library the library with respect to which the lookup is being performed
@@ -6674,17 +6793,17 @@
 
   /**
    * Return the element representing the getter that results from looking up the given getter in the
-   * superclass of this class with respect to the given library, or {@code null} if the look up
+   * superclass of this class with respect to the given library, or `null` if the look up
    * fails. The behavior of this method is defined by the Dart Language Specification in section
    * 12.15.1: <blockquote>The result of looking up getter (respectively setter) <i>m</i> in class
    * <i>C</i> with respect to library <i>L</i> is:
-   * <ul>
-   * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
+   *
+   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
    * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
    * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
    * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.</li>
-   * </ul>
+   * Otherwise, we say that the lookup has failed.
+   *
    * </blockquote>
    * @param getterName the name of the getter being looked up
    * @param library the library with respect to which the lookup is being performed
@@ -6695,16 +6814,16 @@
 
   /**
    * Return the element representing the method that results from looking up the given method in
-   * this class with respect to the given library, or {@code null} if the look up fails. The
+   * this class with respect to the given library, or `null` if the look up fails. The
    * behavior of this method is defined by the Dart Language Specification in section 12.15.1:
    * <blockquote> The result of looking up method <i>m</i> in class <i>C</i> with respect to library
    * <i>L</i> is:
-   * <ul>
-   * <li>If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
+   *
+   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
    * that method is the result of the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then
    * the result of the lookup is the result of looking up method <i>m</i> in <i>S</i> with respect
-   * to <i>L</i>. Otherwise, we say that the lookup has failed.</li>
-   * </ul>
+   * to <i>L</i>. Otherwise, we say that the lookup has failed.
+   *
    * </blockquote>
    * @param methodName the name of the method being looked up
    * @param library the library with respect to which the lookup is being performed
@@ -6715,16 +6834,16 @@
 
   /**
    * Return the element representing the method that results from looking up the given method in the
-   * superclass of this class with respect to the given library, or {@code null} if the look up
+   * superclass of this class with respect to the given library, or `null` if the look up
    * fails. The behavior of this method is defined by the Dart Language Specification in section
    * 12.15.1: <blockquote> The result of looking up method <i>m</i> in class <i>C</i> with respect
    * to library <i>L</i> is:
-   * <ul>
-   * <li>If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
+   *
+   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
    * that method is the result of the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then
    * the result of the lookup is the result of looking up method <i>m</i> in <i>S</i> with respect
-   * to <i>L</i>. Otherwise, we say that the lookup has failed.</li>
-   * </ul>
+   * to <i>L</i>. Otherwise, we say that the lookup has failed.
+   *
    * </blockquote>
    * @param methodName the name of the method being looked up
    * @param library the library with respect to which the lookup is being performed
@@ -6735,17 +6854,17 @@
 
   /**
    * Return the element representing the setter that results from looking up the given setter in
-   * this class with respect to the given library, or {@code null} if the look up fails. The
+   * this class with respect to the given library, or `null` if the look up fails. The
    * behavior of this method is defined by the Dart Language Specification in section 12.16:
    * <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
    * with respect to library <i>L</i> is:
-   * <ul>
-   * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
+   *
+   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
    * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
    * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
    * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.</li>
-   * </ul>
+   * Otherwise, we say that the lookup has failed.
+   *
    * </blockquote>
    * @param setterName the name of the setter being looked up
    * @param library the library with respect to which the lookup is being performed
@@ -6756,17 +6875,17 @@
 
   /**
    * Return the element representing the setter that results from looking up the given setter in the
-   * superclass of this class with respect to the given library, or {@code null} if the look up
+   * superclass of this class with respect to the given library, or `null` if the look up
    * fails. The behavior of this method is defined by the Dart Language Specification in section
    * 12.16: <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class
    * <i>C</i> with respect to library <i>L</i> is:
-   * <ul>
-   * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
+   *
+   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
    * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
    * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
    * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.</li>
-   * </ul>
+   * Otherwise, we say that the lookup has failed.
+   *
    * </blockquote>
    * @param setterName the name of the setter being looked up
    * @param library the library with respect to which the lookup is being performed
@@ -6777,7 +6896,7 @@
 
   /**
    * Return the type resulting from substituting the given arguments for this type's parameters.
-   * This is fully equivalent to {@code substitute(argumentTypes, getTypeArguments())}.
+   * This is fully equivalent to `substitute(argumentTypes, getTypeArguments())`.
    * @param argumentTypes the actual type arguments being substituted for the type parameters
    * @return the result of performing the substitution
    */
@@ -6785,7 +6904,7 @@
   InterfaceType substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes);
 }
 /**
- * The interface {@code ParameterizedType} defines the behavior common to objects representing the
+ * The interface `ParameterizedType` defines the behavior common to objects representing the
  * type with type parameters, such as class and function type alias.
  * @coverage dart.engine.type
  */
@@ -6808,7 +6927,7 @@
   List<TypeVariableElement> get typeVariables;
 }
 /**
- * The interface {@code Type} defines the behavior of objects representing the declared type of
+ * The interface `Type` defines the behavior of objects representing the declared type of
  * elements in the element model.
  * @coverage dart.engine.type
  */
@@ -6822,7 +6941,7 @@
   String get displayName;
 
   /**
-   * Return the element representing the declaration of this type, or {@code null} if the type has
+   * Return the element representing the declaration of this type, or `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
@@ -6830,7 +6949,7 @@
   Element get element;
 
   /**
-   * Return the least upper bound of this type and the given type, or {@code null} if there is no
+   * Return the least upper bound of this type and the given type, or `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
@@ -6838,68 +6957,68 @@
   Type2 getLeastUpperBound(Type2 type);
 
   /**
-   * Return the name of this type, or {@code null} if the type does not have a name, such as when
+   * Return the name of this type, or `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
+   * Return `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
+   * @return `true` if this type is assignable to the given type
    */
   bool isAssignableTo(Type2 type);
 
   /**
-   * Return {@code true} if this type represents the type 'Function' defined in the dart:core
+   * Return `true` if this type represents the type 'Function' defined in the dart:core
    * library.
-   * @return {@code true} if this type represents the type 'Function' defined in the dart:core
+   * @return `true` if this type represents the type 'Function' defined in the dart:core
    * library
    */
-  bool isDartCoreFunction();
+  bool get isDartCoreFunction;
 
   /**
-   * Return {@code true} if this type represents the type 'dynamic'.
-   * @return {@code true} if this type represents the type 'dynamic'
+   * Return `true` if this type represents the type 'dynamic'.
+   * @return `true` if this type represents the type 'dynamic'
    */
-  bool isDynamic();
+  bool get isDynamic;
 
   /**
-   * Return {@code true} if this type is more specific than the given type.
+   * Return `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
+   * @return `true` if this type is more specific than the given type
    */
   bool isMoreSpecificThan(Type2 type);
 
   /**
-   * Return {@code true} if this type represents the type 'Object'.
-   * @return {@code true} if this type represents the type 'Object'
+   * Return `true` if this type represents the type 'Object'.
+   * @return `true` if this type represents the type 'Object'
    */
-  bool isObject();
+  bool get isObject;
 
   /**
-   * Return {@code true} if this type is a subtype of the given type.
+   * Return `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
+   * @return `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
+   * Return `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
+   * @return `true` if this type is a supertype of the given type
    */
   bool isSupertypeOf(Type2 type);
 
   /**
-   * Return {@code true} if this type represents the type 'void'.
-   * @return {@code true} if this type represents the type 'void'
+   * Return `true` if this type represents the type 'void'.
+   * @return `true` if this type represents the type 'void'
    */
-  bool isVoid();
+  bool get isVoid;
 
   /**
    * Return the type resulting from substituting the given arguments for the given parameters in
@@ -6916,7 +7035,7 @@
   Type2 substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes);
 }
 /**
- * The interface {@code TypeVariableType} defines the behavior of objects representing the type
+ * The interface `TypeVariableType` defines the behavior of objects representing the type
  * introduced by a type variable.
  * @coverage dart.engine.type
  */
@@ -6924,7 +7043,7 @@
   TypeVariableElement get element;
 }
 /**
- * The interface {@code VoidType} defines the behavior of the unique object representing the type{@code void}.
+ * The interface `VoidType` defines the behavior of the unique object representing the type`void`.
  * @coverage dart.engine.type
  */
 abstract class VoidType implements Type2 {
diff --git a/pkg/analyzer_experimental/lib/src/generated/engine.dart b/pkg/analyzer_experimental/lib/src/generated/engine.dart
index fd4a2e5..42407bf 100644
--- a/pkg/analyzer_experimental/lib/src/generated/engine.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/engine.dart
@@ -15,7 +15,7 @@
 import 'resolver.dart';
 import 'html.dart' show XmlTagNode, XmlAttributeNode, RecursiveXmlVisitor, HtmlScanner, HtmlScanResult, HtmlParser, HtmlParseResult, HtmlUnit;
 /**
- * The unique instance of the class {@code AnalysisEngine} serves as the entry point for the
+ * The unique instance of the class `AnalysisEngine` serves as the entry point for the
  * functionality provided by the analysis engine.
  * @coverage dart.engine
  */
@@ -48,9 +48,9 @@
   static AnalysisEngine get instance => _UniqueInstance;
 
   /**
-   * Return {@code true} if the given file name is assumed to contain Dart source code.
+   * Return `true` if the given file name is assumed to contain Dart source code.
    * @param fileName the name of the file being tested
-   * @return {@code true} if the given file name is assumed to contain Dart source code
+   * @return `true` if the given file name is assumed to contain Dart source code
    */
   static bool isDartFileName(String fileName) {
     if (fileName == null) {
@@ -60,9 +60,9 @@
   }
 
   /**
-   * Return {@code true} if the given file name is assumed to contain HTML.
+   * Return `true` if the given file name is assumed to contain HTML.
    * @param fileName the name of the file being tested
-   * @return {@code true} if the given file name is assumed to contain HTML
+   * @return `true` if the given file name is assumed to contain HTML
    */
   static bool isHtmlFileName(String fileName) {
     if (fileName == null) {
@@ -82,7 +82,7 @@
    * @return the analysis context that was created
    */
   AnalysisContext createAnalysisContext() {
-    if (Instrumentation.isNullLogger()) {
+    if (Instrumentation.isNullLogger) {
       return new DelegatingAnalysisContextImpl();
     } else {
       return new InstrumentedAnalysisContextImpl.con1(new DelegatingAnalysisContextImpl());
@@ -106,32 +106,32 @@
   }
 }
 /**
- * The interface {@code AnalysisContext} defines the behavior of objects that represent a context in
+ * The interface `AnalysisContext` defines the behavior of objects that represent a context in
  * which a single analysis can be performed and incrementally maintained. The context includes such
  * information as the version of the SDK being analyzed against as well as the package-root used to
- * resolve 'package:' URI's. (Both of which are known indirectly through the {@link SourceFactorysource factory}.)
- * <p>
+ * resolve 'package:' URI's. (Both of which are known indirectly through the [SourceFactorysource factory].)
+ *
  * An analysis context also represents the state of the analysis, which includes knowing which
  * sources have been included in the analysis (either directly or indirectly) and the results of the
- * analysis. Sources must be added and removed from the context using the method{@link #applyChanges(ChangeSet)}, which is also used to notify the context when sources have been
+ * analysis. Sources must be added and removed from the context using the method[applyChanges], which is also used to notify the context when sources have been
  * modified and, consequently, previously known results might have been invalidated.
- * <p>
+ *
  * There are two ways to access the results of the analysis. The most common is to use one of the
  * 'get' methods to access the results. The 'get' methods have the advantage that they will always
  * return quickly, but have the disadvantage that if the results are not currently available they
  * will return either nothing or in some cases an incomplete result. The second way to access
  * results is by using one of the 'compute' methods. The 'compute' methods will always attempt to
  * compute the requested results but might block the caller for a significant period of time.
- * <p>
+ *
  * When results have been invalidated, have never been computed (as is the case for newly added
  * sources), or have been removed from the cache, they are <b>not</b> automatically recreated. They
  * will only be recreated if one of the 'compute' methods is invoked.
- * <p>
+ *
  * However, this is not always acceptable. Some clients need to keep the analysis results
  * up-to-date. For such clients there is a mechanism that allows them to incrementally perform
  * needed analysis and get notified of the consequent changes to the analysis results. This
- * mechanism is realized by the method {@link #performAnalysisTask()}.
- * <p>
+ * mechanism is realized by the method [performAnalysisTask].
+ *
  * Analysis engine allows for having more than one context. This can be used, for example, to
  * perform one analysis based on the state of files on disk and a separate analysis based on the
  * state of those files in open editors. It can also be used to perform an analysis based on a
@@ -148,7 +148,7 @@
 
   /**
    * Return the documentation comment for the given element as it appears in the original source
-   * (complete with the beginning and ending delimiters), or {@code null} if the element does not
+   * (complete with the beginning and ending delimiters), or `null` if the element does not
    * have a documentation comment associated with it. This can be a long-running operation if the
    * information needed to access the comment is not cached.
    * @param element the element whose documentation comment is to be returned
@@ -185,7 +185,7 @@
   HtmlElement computeHtmlElement(Source source);
 
   /**
-   * Return the kind of the given source, computing it's kind if it is not already known. Return{@link SourceKind#UNKNOWN} if the source is not contained in this context.
+   * Return the kind of the given source, computing it's kind if it is not already known. Return[SourceKind#UNKNOWN] if the source is not contained in this context.
    * @param source the source whose kind is to be returned
    * @return the kind of the given source
    * @see #getKindOf(Source)
@@ -206,7 +206,7 @@
   LibraryElement computeLibraryElement(Source source);
 
   /**
-   * Return the line information for the given source, or {@code null} if the source is not of a
+   * Return the line information for the given source, or `null` if the source is not of a
    * recognized kind (neither a Dart nor HTML file). If the line information was not previously
    * known it will be created. The line information is used to map offsets from the beginning of the
    * source to line and column pairs.
@@ -234,7 +234,7 @@
   AnalysisOptions get analysisOptions;
 
   /**
-   * Return the element referenced by the given location, or {@code null} if the element is not
+   * Return the element referenced by the given location, or `null` if the element is not
    * immediately available or if there is no element with the given location. The latter condition
    * can occur, for example, if the location describes an element from a different context or if the
    * element has been removed from this context as a result of some change since it was originally
@@ -256,7 +256,7 @@
   AnalysisErrorInfo getErrors(Source source);
 
   /**
-   * Return the element model corresponding to the HTML file defined by the given source, or{@code null} if the source does not represent an HTML file, the element representing the file
+   * Return the element model corresponding to the HTML file defined by the given source, or`null` if the source does not represent an HTML file, the element representing the file
    * has not yet been created, or the analysis of the HTML file failed for some reason.
    * @param source the source defining the HTML file whose element model is to be returned
    * @return the element model corresponding to the HTML file defined by the given source
@@ -281,7 +281,7 @@
   List<Source> get htmlSources;
 
   /**
-   * Return the kind of the given source, or {@code null} if the kind is not known to this context.
+   * Return the kind of the given source, or `null` if the kind is not known to this context.
    * @param source the source whose kind is to be returned
    * @return the kind of the given source
    * @see #computeKindOf(Source)
@@ -331,7 +331,7 @@
   List<Source> getLibrariesDependingOn(Source librarySource);
 
   /**
-   * Return the element model corresponding to the library defined by the given source, or{@code null} if the element model does not currently exist or if the library cannot be analyzed
+   * Return the element model corresponding to the library defined by the given source, or`null` if the element model does not currently exist or if the library cannot be analyzed
    * for some reason.
    * @param source the source defining the library whose element model is to be returned
    * @return the element model corresponding to the library defined by the given source
@@ -347,7 +347,7 @@
   List<Source> get librarySources;
 
   /**
-   * Return the line information for the given source, or {@code null} if the line information is
+   * Return the line information for the given source, or `null` if the line information is
    * not known. The line information is used to map offsets from the beginning of the source to line
    * and column pairs.
    * @param source the source whose line information is to be returned
@@ -357,7 +357,7 @@
   LineInfo getLineInfo(Source source);
 
   /**
-   * Return a fully resolved AST for a single compilation unit within the given library, or{@code null} if the resolved AST is not already computed.
+   * Return a fully resolved AST for a single compilation unit within the given library, or`null` if the resolved AST is not already computed.
    * @param unitSource the source of the compilation unit
    * @param library the library containing the compilation unit
    * @return a fully resolved AST for the compilation unit
@@ -366,7 +366,7 @@
   CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library);
 
   /**
-   * Return a fully resolved AST for a single compilation unit within the given library, or{@code null} if the resolved AST is not already computed.
+   * Return a fully resolved AST for a single compilation unit within the given library, or`null` if the resolved AST is not already computed.
    * @param unitSource the source of the compilation unit
    * @param librarySource the source of the defining compilation unit of the library containing the
    * compilation unit
@@ -382,28 +382,28 @@
   SourceFactory get sourceFactory;
 
   /**
-   * Return {@code true} if the given source is known to be the defining compilation unit of a
+   * Return `true` if the given source is known to be the defining compilation unit of a
    * library that can be run on a client (references 'dart:html', either directly or indirectly).
-   * <p>
-   * <b>Note:</b> In addition to the expected case of returning {@code false} if the source is known
-   * to be a library that cannot be run on a client, this method will also return {@code false} if
+   *
+   * <b>Note:</b> In addition to the expected case of returning `false` if the source is known
+   * to be a library that cannot be run on a client, this method will also return `false` if
    * the source is not known to be a library or if we do not know whether it can be run on a client.
    * @param librarySource the source being tested
-   * @return {@code true} if the given source is known to be a library that can be run on a client
+   * @return `true` if the given source is known to be a library that can be run on a client
    */
   bool isClientLibrary(Source librarySource);
 
   /**
-   * Return {@code true} if the given source is known to be the defining compilation unit of a
+   * Return `true` if the given source is known to be the defining compilation unit of a
    * library that can be run on the server (does not reference 'dart:html', either directly or
    * indirectly).
-   * <p>
-   * <b>Note:</b> In addition to the expected case of returning {@code false} if the source is known
-   * to be a library that cannot be run on the server, this method will also return {@code false} if
+   *
+   * <b>Note:</b> In addition to the expected case of returning `false` if the source is known
+   * to be a library that cannot be run on the server, this method will also return `false` if
    * the source is not known to be a library or if we do not know whether it can be run on the
    * server.
    * @param librarySource the source being tested
-   * @return {@code true} if the given source is known to be a library that can be run on the server
+   * @return `true` if the given source is known to be a library that can be run on the server
    */
   bool isServerLibrary(Source librarySource);
 
@@ -429,7 +429,7 @@
    * may not be resolved, and may have a slightly different structure depending upon whether it is
    * resolved.
    * @param source the HTML source to be parsed
-   * @return the parse result (not {@code null})
+   * @return the parse result (not `null`)
    * @throws AnalysisException if the analysis could not be performed
    */
   HtmlUnit parseHtmlUnit(Source source);
@@ -438,7 +438,7 @@
    * Perform the next unit of work required to keep the analysis results up-to-date and return
    * information about the consequent changes to the analysis results. If there were no results the
    * returned array will be empty. If there are no more units of work required, then this method
-   * returns {@code null}. This method can be long running.
+   * returns `null`. This method can be long running.
    * @return an array containing notices of changes to the analysis results
    */
   List<ChangeNotice> performAnalysisTask();
@@ -484,7 +484,7 @@
   /**
    * Set the contents of the given source to the given contents and mark the source as having
    * changed. This has the effect of overriding the default contents of the source. If the contents
-   * are {@code null} the override is removed so that the default contents will be returned.
+   * are `null` the override is removed so that the default contents will be returned.
    * @param source the source whose contents are being overridden
    * @param contents the new contents of the source
    */
@@ -500,33 +500,33 @@
   void set sourceFactory(SourceFactory factory);
 
   /**
-   * Given a collection of sources with content that has changed, return an {@link Iterable}identifying the sources that need to be resolved.
-   * @param changedSources an array of sources (not {@code null}, contains no {@code null}s)
+   * Given a collection of sources with content that has changed, return an [Iterable]identifying the sources that need to be resolved.
+   * @param changedSources an array of sources (not `null`, contains no `null`s)
    * @return An iterable returning the sources to be resolved
    */
   Iterable<Source> sourcesToResolve(List<Source> changedSources);
 }
 /**
- * The interface {@code AnalysisErrorInfo} contains the analysis errors and line information for the
+ * The interface `AnalysisErrorInfo` contains the analysis errors and line information for the
  * errors.
  */
 abstract class AnalysisErrorInfo {
 
   /**
-   * Return the errors that as a result of the analysis, or {@code null} if there were no errors.
+   * Return the errors that as a result of the analysis, or `null` if there were no errors.
    * @return the errors as a result of the analysis
    */
   List<AnalysisError> get errors;
 
   /**
-   * Return the line information associated with the errors, or {@code null} if there were no
+   * Return the line information associated with the errors, or `null` if there were no
    * errors.
    * @return the line information associated with the errors
    */
   LineInfo get lineInfo;
 }
 /**
- * Instances of the class {@code AnalysisException} represent an exception that occurred during the
+ * Instances of the class `AnalysisException` represent an exception that occurred during the
  * analysis of one or more sources.
  * @coverage dart.engine
  */
@@ -573,27 +573,27 @@
   }
 }
 /**
- * The interface {@code AnalysisOptions} defines the behavior of objects that provide access to a
+ * The interface `AnalysisOptions` defines the behavior of objects that provide access to a
  * set of analysis options used to control the behavior of an analysis context.
  */
 abstract class AnalysisOptions {
 
   /**
-   * Return {@code true} if analysis is to use strict mode. In strict mode, error reporting is based
+   * Return `true` if analysis is to use strict mode. In strict mode, error reporting is based
    * exclusively on the static type information.
-   * @return {@code true} if analysis is to use strict mode
+   * @return `true` if analysis is to use strict mode
    */
   bool get strictMode;
 }
 /**
- * The interface {@code ChangeNotice} defines the behavior of objects that represent a change to the
+ * The interface `ChangeNotice` defines the behavior of objects that represent a change to the
  * analysis results associated with a given source.
  * @coverage dart.engine
  */
 abstract class ChangeNotice implements AnalysisErrorInfo {
 
   /**
-   * Return the fully resolved AST that changed as a result of the analysis, or {@code null} if the
+   * Return the fully resolved AST that changed as a result of the analysis, or `null` if the
    * AST was not changed.
    * @return the fully resolved AST that changed as a result of the analysis
    */
@@ -606,7 +606,7 @@
   Source get source;
 }
 /**
- * Instances of the class {@code ChangeSet} indicate what sources have been added, changed, or
+ * Instances of the class `ChangeSet` indicate what sources have been added, changed, or
  * removed.
  * @coverage dart.engine
  */
@@ -675,10 +675,10 @@
   List<SourceContainer> get removedContainers => _removedContainers;
 
   /**
-   * Return {@code true} if this change set does not contain any changes.
-   * @return {@code true} if this change set does not contain any changes
+   * Return `true` if this change set does not contain any changes.
+   * @return `true` if this change set does not contain any changes
    */
-  bool isEmpty() => _added2.isEmpty && _changed2.isEmpty && _removed2.isEmpty && _removedContainers.isEmpty;
+  bool get isEmpty => _added2.isEmpty && _changed2.isEmpty && _removed2.isEmpty && _removedContainers.isEmpty;
 
   /**
    * Record that the specified source has been removed.
@@ -701,7 +701,7 @@
   }
 }
 /**
- * The interface {@code DartEntry} defines the behavior of objects that maintain the information
+ * The interface `DartEntry` defines the behavior of objects that maintain the information
  * cached by an analysis context about an individual Dart file.
  * @coverage dart.engine
  */
@@ -776,14 +776,14 @@
 
   /**
    * Return a valid parsed compilation unit, either an unresolved AST structure or the result of
-   * resolving the AST structure in the context of some library, or {@code null} if there is no
+   * resolving the AST structure in the context of some library, or `null` if there is no
    * parsed compilation unit available.
    * @return a valid parsed compilation unit
    */
   CompilationUnit get anyParsedCompilationUnit;
 
   /**
-   * Return the result of resolving the compilation unit as part of any library, or {@code null} if
+   * Return the result of resolving the compilation unit as part of any library, or `null` if
    * there is no cached resolved compilation unit.
    * @return any resolved compilation unit
    */
@@ -801,7 +801,7 @@
 
   /**
    * Return the value of the data represented by the given descriptor in the context of the given
-   * library, or {@code null} if the data represented by the descriptor is not in the cache.
+   * library, or `null` if the data represented by the descriptor is not in the cache.
    * @param descriptor the descriptor representing which data is to be returned
    * @param librarySource the source of the defining compilation unit of the library that is the
    * context for the data
@@ -811,7 +811,7 @@
   DartEntryImpl get writableCopy;
 }
 /**
- * Instances of the class {@code DartEntryImpl} implement a {@link DartEntry}.
+ * Instances of the class `DartEntryImpl` implement a [DartEntry].
  * @coverage dart.engine
  */
 class DartEntryImpl extends SourceEntryImpl implements DartEntry {
@@ -832,7 +832,7 @@
   CacheState _parsedUnitState = CacheState.INVALID;
 
   /**
-   * The parsed compilation unit, or {@code null} if the parsed compilation unit is not currently
+   * The parsed compilation unit, or `null` if the parsed compilation unit is not currently
    * cached.
    */
   CompilationUnit _parsedUnit;
@@ -843,7 +843,7 @@
   CacheState _parseErrorsState = CacheState.INVALID;
 
   /**
-   * The errors produced while scanning and parsing the compilation unit, or {@code null} if the
+   * The errors produced while scanning and parsing the compilation unit, or `null` if the
    * errors are not currently cached.
    */
   List<AnalysisError> _parseErrors = AnalysisError.NO_ERRORS;
@@ -873,7 +873,7 @@
 
   /**
    * The information known as a result of resolving this compilation unit as part of the library
-   * that contains this unit. This field will never be {@code null}.
+   * that contains this unit. This field will never be `null`.
    */
   DartEntryImpl_ResolutionState _resolutionState = new DartEntryImpl_ResolutionState();
 
@@ -883,7 +883,7 @@
   CacheState _elementState = CacheState.INVALID;
 
   /**
-   * The element representing the library, or {@code null} if the element is not currently cached.
+   * The element representing the library, or `null` if the element is not currently cached.
    */
   LibraryElement _element;
 
@@ -893,7 +893,7 @@
   CacheState _publicNamespaceState = CacheState.INVALID;
 
   /**
-   * The public namespace of the library, or {@code null} if the namespace is not currently cached.
+   * The public namespace of the library, or `null` if the namespace is not currently cached.
    */
   Namespace _publicNamespace;
 
@@ -908,7 +908,7 @@
   CacheState _launchableState = CacheState.INVALID;
 
   /**
-   * An integer holding bit masks such as {@link #LAUNCHABLE} and {@link #CLIENT_CODE}.
+   * An integer holding bit masks such as [LAUNCHABLE] and [CLIENT_CODE].
    */
   int _bitmask = 0;
 
@@ -1280,7 +1280,7 @@
 
   /**
    * Set the value of the data represented by the given descriptor in the context of the given
-   * library to the given value, and set the state of that data to {@link CacheState#VALID}.
+   * library to the given value, and set the state of that data to [CacheState#VALID].
    * @param descriptor the descriptor representing which data is to have its value set
    * @param librarySource the source of the defining compilation unit of the library that is the
    * context for the data
@@ -1321,8 +1321,8 @@
 
   /**
    * Return a resolution state for the specified library, creating one as necessary.
-   * @param librarySource the library source (not {@code null})
-   * @return the resolution state (not {@code null})
+   * @param librarySource the library source (not `null`)
+   * @return the resolution state (not `null`)
    */
   DartEntryImpl_ResolutionState getOrCreateResolutionState(Source librarySource2) {
     DartEntryImpl_ResolutionState state = _resolutionState;
@@ -1360,13 +1360,13 @@
   }
 }
 /**
- * Instances of the class {@code ResolutionState} represent the information produced by resolving
+ * Instances of the class `ResolutionState` represent the information produced by resolving
  * a compilation unit as part of a specific library.
  */
 class DartEntryImpl_ResolutionState {
 
   /**
-   * The next resolution state or {@code null} if none.
+   * The next resolution state or `null` if none.
    */
   DartEntryImpl_ResolutionState _nextState;
 
@@ -1383,7 +1383,7 @@
   CacheState _resolvedUnitState = CacheState.INVALID;
 
   /**
-   * The resolved compilation unit, or {@code null} if the resolved compilation unit is not
+   * The resolved compilation unit, or `null` if the resolved compilation unit is not
    * currently cached.
    */
   CompilationUnit _resolvedUnit;
@@ -1394,7 +1394,7 @@
   CacheState _resolutionErrorsState = CacheState.INVALID;
 
   /**
-   * The errors produced while resolving the compilation unit, or {@code null} if the errors are
+   * The errors produced while resolving the compilation unit, or `null` if the errors are
    * not currently cached.
    */
   List<AnalysisError> _resolutionErrors = AnalysisError.NO_ERRORS;
@@ -1443,7 +1443,7 @@
   }
 }
 /**
- * Instances of the class {@code DataDescriptor} are immutable constants representing data that can
+ * Instances of the class `DataDescriptor` are immutable constants representing data that can
  * be stored in the cache.
  */
 class DataDescriptor<E> {
@@ -1463,7 +1463,7 @@
   String toString() => _name;
 }
 /**
- * The interface {@code HtmlEntry} defines the behavior of objects that maintain the information
+ * The interface `HtmlEntry` defines the behavior of objects that maintain the information
  * cached by an analysis context about an individual HTML file.
  * @coverage dart.engine
  */
@@ -1502,7 +1502,7 @@
   HtmlEntryImpl get writableCopy;
 }
 /**
- * Instances of the class {@code HtmlEntryImpl} implement an {@link HtmlEntry}.
+ * Instances of the class `HtmlEntryImpl` implement an [HtmlEntry].
  * @coverage dart.engine
  */
 class HtmlEntryImpl extends SourceEntryImpl implements HtmlEntry {
@@ -1513,7 +1513,7 @@
   CacheState _parsedUnitState = CacheState.INVALID;
 
   /**
-   * The parsed HTML unit, or {@code null} if the parsed HTML unit is not currently cached.
+   * The parsed HTML unit, or `null` if the parsed HTML unit is not currently cached.
    */
   HtmlUnit _parsedUnit;
 
@@ -1523,7 +1523,7 @@
   CacheState _resolutionErrorsState = CacheState.INVALID;
 
   /**
-   * The errors produced while resolving the compilation unit, or {@code null} if the errors are not
+   * The errors produced while resolving the compilation unit, or `null` if the errors are not
    * currently cached.
    */
   List<AnalysisError> _resolutionErrors = AnalysisError.NO_ERRORS;
@@ -1534,7 +1534,7 @@
   CacheState _resolvedUnitState = CacheState.INVALID;
 
   /**
-   * The resolved HTML unit, or {@code null} if the resolved HTML unit is not currently cached.
+   * The resolved HTML unit, or `null` if the resolved HTML unit is not currently cached.
    */
   HtmlUnit _resolvedUnit;
 
@@ -1544,7 +1544,7 @@
   CacheState _referencedLibrariesState = CacheState.INVALID;
 
   /**
-   * The list of libraries referenced in the HTML, or {@code null} if the list is not currently
+   * The list of libraries referenced in the HTML, or `null` if the list is not currently
    * cached. Note that this list does not include libraries defined directly within the HTML file.
    */
   List<Source> _referencedLibraries = Source.EMPTY_ARRAY;
@@ -1555,7 +1555,7 @@
   CacheState _elementState = CacheState.INVALID;
 
   /**
-   * The element representing the HTML file, or {@code null} if the element is not currently cached.
+   * The element representing the HTML file, or `null` if the element is not currently cached.
    */
   HtmlElement _element;
   List<AnalysisError> get allErrors {
@@ -1658,9 +1658,9 @@
   }
 }
 /**
- * The interface {@code SourceEntry} defines the behavior of objects that maintain the information
+ * The interface `SourceEntry` defines the behavior of objects that maintain the information
  * cached by an analysis context about an individual source, no matter what kind of source it is.
- * <p>
+ *
  * Source entries should be treated as if they were immutable unless a writable copy of the entry
  * has been obtained and has not yet been made visible to other threads.
  * @coverage dart.engine
@@ -1673,7 +1673,7 @@
   static final DataDescriptor<LineInfo> LINE_INFO = new DataDescriptor<LineInfo>("SourceEntry.LINE_INFO");
 
   /**
-   * Return the kind of the source, or {@code null} if the kind is not currently cached.
+   * Return the kind of the source, or `null` if the kind is not currently cached.
    * @return the kind of the source
    */
   SourceKind get kind;
@@ -1693,7 +1693,7 @@
   CacheState getState(DataDescriptor<Object> descriptor);
 
   /**
-   * Return the value of the data represented by the given descriptor, or {@code null} if the data
+   * Return the value of the data represented by the given descriptor, or `null` if the data
    * represented by the descriptor is not in the cache.
    * @param descriptor the descriptor representing which data is to be returned
    * @return the value of the data represented by the given descriptor
@@ -1708,7 +1708,7 @@
   SourceEntryImpl get writableCopy;
 }
 /**
- * Instances of the abstract class {@code SourceEntryImpl} implement the behavior common to all{@link SourceEntry source entries}.
+ * Instances of the abstract class `SourceEntryImpl` implement the behavior common to all[SourceEntry source entries].
  * @coverage dart.engine
  */
 abstract class SourceEntryImpl implements SourceEntry {
@@ -1725,7 +1725,7 @@
   CacheState _lineInfoState = CacheState.INVALID;
 
   /**
-   * The line information computed for the source, or {@code null} if the line information is not
+   * The line information computed for the source, or `null` if the line information is not
    * currently cached.
    */
   LineInfo _lineInfo;
@@ -1810,8 +1810,8 @@
   }
 }
 /**
- * Instances of the class {@code AnalysisContextImpl} implement an {@link AnalysisContext analysis
- * context}.
+ * Instances of the class `AnalysisContextImpl` implement an [AnalysisContext analysis
+ * context].
  * @coverage dart.engine
  */
 class AnalysisContextImpl implements InternalAnalysisContext {
@@ -1884,7 +1884,7 @@
     _sourceMap[source] = info;
   }
   void applyChanges(ChangeSet changeSet) {
-    if (changeSet.isEmpty()) {
+    if (changeSet.isEmpty) {
       return;
     }
     {
@@ -1906,7 +1906,7 @@
       }
       if (addedDartSource) {
         for (MapEntry<Source, SourceEntry> mapEntry in getMapEntrySet(_sourceMap)) {
-          if (!mapEntry.getKey().isInSystemLibrary() && mapEntry.getValue() is DartEntry) {
+          if (!mapEntry.getKey().isInSystemLibrary && mapEntry.getValue() is DartEntry) {
             DartEntryImpl dartCopy = ((mapEntry.getValue() as DartEntry)).writableCopy;
             dartCopy.invalidateAllResolutionInformation();
             mapEntry.setValue(dartCopy);
@@ -2172,7 +2172,7 @@
       for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
         Source source = entry.getKey();
         SourceEntry sourceEntry = entry.getValue();
-        if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary()) {
+        if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary) {
           sources.add(source);
         }
       }
@@ -2185,7 +2185,7 @@
       for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
         Source source = entry.getKey();
         SourceEntry sourceEntry = entry.getValue();
-        if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary()) {
+        if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary) {
           sources.add(source);
         }
       }
@@ -2496,9 +2496,9 @@
   }
 
   /**
-   * Return a list of the sources that would be processed by {@link #performAnalysisTask()}. This
+   * Return a list of the sources that would be processed by [performAnalysisTask]. This
    * method is intended to be used for testing purposes only.
-   * @return a list of the sources that would be processed by {@link #performAnalysisTask()}
+   * @return a list of the sources that would be processed by [performAnalysisTask]
    */
   List<Source> get sourcesNeedingProcessing {
     List<Source> sources = new List<Source>();
@@ -2527,8 +2527,8 @@
 
   /**
    * Record that the given source was just accessed for some unspecified purpose.
-   * <p>
-   * Note: This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   *
+   * Note: This method must only be invoked while we are synchronized on [cacheLock].
    * @param source the source that was accessed
    */
   void accessed(Source source) {
@@ -2559,8 +2559,8 @@
 
   /**
    * Add all of the sources contained in the given source container to the given list of sources.
-   * <p>
-   * Note: This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   *
+   * Note: This method must only be invoked while we are synchronized on [cacheLock].
    * @param sources the list to which sources are to be added
    * @param container the source container containing the sources to be added to the list
    */
@@ -2573,10 +2573,10 @@
   }
 
   /**
-   * Return {@code true} if the given array of sources contains the given source.
+   * Return `true` if the given array of sources contains the given source.
    * @param sources the sources being searched
    * @param targetSource the source being searched for
-   * @return {@code true} if the given source is in the array
+   * @return `true` if the given source is in the array
    */
   bool contains(List<Source> sources, Source targetSource) {
     for (Source source in sources) {
@@ -2588,10 +2588,10 @@
   }
 
   /**
-   * Return {@code true} if the given array of sources contains any of the given target sources.
+   * Return `true` if the given array of sources contains any of the given target sources.
    * @param sources the sources being searched
    * @param targetSources the sources being searched for
-   * @return {@code true} if any of the given target sources are in the array
+   * @return `true` if any of the given target sources are in the array
    */
   bool containsAny(List<Source> sources, List<Source> targetSources) {
     for (Source targetSource in targetSources) {
@@ -2604,7 +2604,7 @@
 
   /**
    * Create a source information object suitable for the given source. Return the source information
-   * object that was created, or {@code null} if the source should not be tracked by this context.
+   * object that was created, or `null` if the source should not be tracked by this context.
    * @param source the source for which an information object is being created
    * @return the source information object that was created
    */
@@ -2622,7 +2622,7 @@
   }
 
   /**
-   * Disable flushing information from the cache until {@link #enableCacheRemoval()} has been
+   * Disable flushing information from the cache until [enableCacheRemoval] has been
    * called.
    */
   void disableCacheRemoval() {
@@ -2659,7 +2659,7 @@
 
   /**
    * Search the compilation units that are part of the given library and return the element
-   * representing the compilation unit with the given source. Return {@code null} if there is no
+   * representing the compilation unit with the given source. Return `null` if there is no
    * such compilation unit.
    * @param libraryElement the element representing the library being searched through
    * @param unitSource the source for the compilation unit whose element is to be returned
@@ -2679,13 +2679,13 @@
   }
 
   /**
-   * Return the compilation unit information associated with the given source, or {@code null} if
+   * Return the compilation unit information associated with the given source, or `null` if
    * the source is not known to this context. This method should be used to access the compilation
    * unit information rather than accessing the compilation unit map directly because sources in the
    * SDK are implicitly part of every analysis context and are therefore only added to the map when
    * first accessed.
-   * <p>
-   * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   *
+   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
    * @param source the source for which information is being sought
    * @return the compilation unit information associated with the given source
    */
@@ -2702,13 +2702,13 @@
   }
 
   /**
-   * Return the HTML unit information associated with the given source, or {@code null} if the
+   * Return the HTML unit information associated with the given source, or `null` if the
    * source is not known to this context. This method should be used to access the HTML unit
    * information rather than accessing the HTML unit map directly because sources in the SDK are
    * implicitly part of every analysis context and are therefore only added to the map when first
    * accessed.
-   * <p>
-   * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   *
+   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
    * @param source the source for which information is being sought
    * @return the HTML unit information associated with the given source
    */
@@ -2754,7 +2754,7 @@
   }
 
   /**
-   * Return the cache entry associated with the given source, or {@code null} if there is no entry
+   * Return the cache entry associated with the given source, or `null` if there is no entry
    * associated with the source.
    * @param source the source for which a cache entry is being sought
    * @return the source cache entry associated with the given source
@@ -2766,12 +2766,12 @@
   }
 
   /**
-   * Return the source information associated with the given source, or {@code null} if the source
+   * Return the source information associated with the given source, or `null` if the source
    * is not known to this context. This method should be used to access the source information
    * rather than accessing the source map directly because sources in the SDK are implicitly part of
    * every analysis context and are therefore only added to the map when first accessed.
-   * <p>
-   * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   *
+   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
    * @param source the source for which information is being sought
    * @return the source information associated with the given source
    */
@@ -2801,10 +2801,10 @@
   }
 
   /**
-   * Return {@code true} if the given compilation unit has a part-of directive but no library
+   * Return `true` if the given compilation unit has a part-of directive but no library
    * directive.
    * @param unit the compilation unit being tested
-   * @return {@code true} if the compilation unit has a part-of directive
+   * @return `true` if the compilation unit has a part-of directive
    */
   bool hasPartOfDirective(CompilationUnit unit) {
     bool hasPartOf = false;
@@ -2898,8 +2898,8 @@
 
   /**
    * Invalidate all of the results computed by this context.
-   * <p>
-   * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   *
+   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
    */
   void invalidateAllResults() {
     for (MapEntry<Source, SourceEntry> mapEntry in getMapEntrySet(_sourceMap)) {
@@ -2941,11 +2941,11 @@
   }
 
   /**
-   * Return {@code true} if this library is, or depends on, dart:html.
+   * Return `true` if this library is, or depends on, dart:html.
    * @param library the library being tested
    * @param visitedLibraries a collection of the libraries that have been visited, used to prevent
    * infinite recursion
-   * @return {@code true} if this library is, or depends on, dart:html
+   * @return `true` if this library is, or depends on, dart:html
    */
   bool isClient(LibraryElement library, Source htmlSource, Set<LibraryElement> visitedLibraries) {
     if (visitedLibraries.contains(library)) {
@@ -2970,9 +2970,9 @@
 
   /**
    * Perform a single analysis task.
-   * <p>
-   * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}.
-   * @return {@code true} if work was done, implying that there might be more work to be done
+   *
+   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
+   * @return `true` if work was done, implying that there might be more work to be done
    */
   bool performSingleAnalysisTask() {
     for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
@@ -3122,12 +3122,12 @@
   }
 
   /**
-   * Create an entry for the newly added source. Return {@code true} if the new source is a Dart
+   * Create an entry for the newly added source. Return `true` if the new source is a Dart
    * file.
-   * <p>
-   * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   *
+   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
    * @param source the source that has been added
-   * @return {@code true} if the new source is a Dart file
+   * @return `true` if the new source is a Dart file
    */
   bool sourceAvailable(Source source) {
     SourceEntry sourceEntry = _sourceMap[source];
@@ -3138,7 +3138,7 @@
   }
 
   /**
-   * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
    * @param source the source that has been changed
    */
   void sourceChanged(Source source) {
@@ -3152,28 +3152,21 @@
       htmlCopy.setState(HtmlEntry.RESOLVED_UNIT, CacheState.INVALID);
       _sourceMap[source] = htmlCopy;
     } else if (sourceEntry is DartEntry) {
-      Set<Source> librariesToInvalidate = new Set<Source>();
       List<Source> containingLibraries = getLibrariesContaining(source);
-      for (Source containingLibrary in containingLibraries) {
-        javaSetAdd(librariesToInvalidate, containingLibrary);
-        for (Source dependentLibrary in getLibrariesDependingOn(containingLibrary)) {
-          javaSetAdd(librariesToInvalidate, dependentLibrary);
-        }
-      }
       DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
       dartCopy.setState(SourceEntry.LINE_INFO, CacheState.INVALID);
       dartCopy.setState(DartEntry.PARSE_ERRORS, CacheState.INVALID);
       dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.INVALID);
       dartCopy.setState(DartEntry.SOURCE_KIND, CacheState.INVALID);
       _sourceMap[source] = dartCopy;
-      for (Source library in librariesToInvalidate) {
+      for (Source library in containingLibraries) {
         invalidateLibraryResolution(library);
       }
     }
   }
 
   /**
-   * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}.
+   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
    * @param source the source that has been deleted
    */
   void sourceRemoved(Source source) {
@@ -3194,7 +3187,7 @@
   }
 }
 /**
- * Instances of the class {@code ScanResult} represent the results of scanning a source.
+ * Instances of the class `ScanResult` represent the results of scanning a source.
  */
 class AnalysisContextImpl_ScanResult {
 
@@ -3266,18 +3259,18 @@
   }
 }
 /**
- * Instances of the class {@code AnalysisErrorInfoImpl} represent the analysis errors and line info
+ * Instances of the class `AnalysisErrorInfoImpl` represent the analysis errors and line info
  * associated with a source.
  */
 class AnalysisErrorInfoImpl implements AnalysisErrorInfo {
 
   /**
-   * The analysis errors associated with a source, or {@code null} if there are no errors.
+   * The analysis errors associated with a source, or `null` if there are no errors.
    */
   List<AnalysisError> _errors;
 
   /**
-   * The line information associated with the errors, or {@code null} if there are no errors.
+   * The line information associated with the errors, or `null` if there are no errors.
    */
   LineInfo _lineInfo;
 
@@ -3292,20 +3285,20 @@
   }
 
   /**
-   * Return the errors of analysis, or {@code null} if there were no errors.
+   * Return the errors of analysis, or `null` if there were no errors.
    * @return the errors as a result of the analysis
    */
   List<AnalysisError> get errors => _errors;
 
   /**
-   * Return the line information associated with the errors, or {@code null} if there were no
+   * Return the line information associated with the errors, or `null` if there were no
    * errors.
    * @return the line information associated with the errors
    */
   LineInfo get lineInfo => _lineInfo;
 }
 /**
- * Instances of the class {@code AnalysisOptions} represent a set of analysis options used to
+ * Instances of the class `AnalysisOptions` represent a set of analysis options used to
  * control the behavior of an analysis context.
  */
 class AnalysisOptionsImpl implements AnalysisOptions {
@@ -3317,78 +3310,78 @@
   bool _strictMode = false;
 
   /**
-   * Return {@code true} if analysis is to use strict mode. In strict mode, error reporting is based
+   * Return `true` if analysis is to use strict mode. In strict mode, error reporting is based
    * exclusively on the static type information.
-   * @return {@code true} if analysis is to use strict mode
+   * @return `true` if analysis is to use strict mode
    */
   bool get strictMode => _strictMode;
 
   /**
    * Set whether analysis is to use strict mode to the given value. In strict mode, error reporting
    * is based exclusively on the static type information.
-   * @param isStrict {@code true} if analysis is to use strict mode
+   * @param isStrict `true` if analysis is to use strict mode
    */
   void set strictMode(bool isStrict) {
     _strictMode = isStrict;
   }
 }
 /**
- * The enumeration {@code CacheState} defines the possible states of cached data.
+ * The enumeration `CacheState` defines the possible states of cached data.
  */
 class CacheState implements Comparable<CacheState> {
 
   /**
    * The data is not in the cache and the last time an attempt was made to compute the data an
    * exception occurred, making it pointless to attempt.
-   * <p>
+   *
    * Valid Transitions:
-   * <ul>
-   * <li>{@link #INVALID} if a source was modified that might cause the data to be computable</li>
-   * </ul>
+   *
+   * * [INVALID] if a source was modified that might cause the data to be computable
+   *
    */
   static final CacheState ERROR = new CacheState('ERROR', 0);
 
   /**
    * The data is not in the cache because it was flushed from the cache in order to control memory
    * usage. If the data is recomputed, results do not need to be reported.
-   * <p>
+   *
    * Valid Transitions:
-   * <ul>
-   * <li>{@link #IN_PROCESS} if the data is being recomputed</li>
-   * <li>{@link #INVALID} if a source was modified that causes the data to need to be recomputed</li>
-   * </ul>
+   *
+   * * [IN_PROCESS] if the data is being recomputed
+   * * [INVALID] if a source was modified that causes the data to need to be recomputed
+   *
    */
   static final CacheState FLUSHED = new CacheState('FLUSHED', 1);
 
   /**
    * The data might or might not be in the cache but is in the process of being recomputed.
-   * <p>
+   *
    * Valid Transitions:
-   * <ul>
-   * <li>{@link #ERROR} if an exception occurred while trying to compute the data</li>
-   * <li>{@link #VALID} if the data was successfully computed and stored in the cache</li>
-   * </ul>
+   *
+   * * [ERROR] if an exception occurred while trying to compute the data
+   * * [VALID] if the data was successfully computed and stored in the cache
+   *
    */
   static final CacheState IN_PROCESS = new CacheState('IN_PROCESS', 2);
 
   /**
    * The data is not in the cache and needs to be recomputed so that results can be reported.
-   * <p>
+   *
    * Valid Transitions:
-   * <ul>
-   * <li>{@link #IN_PROCESS} if an attempt is being made to recompute the data</li>
-   * </ul>
+   *
+   * * [IN_PROCESS] if an attempt is being made to recompute the data
+   *
    */
   static final CacheState INVALID = new CacheState('INVALID', 3);
 
   /**
    * The data is in the cache and up-to-date.
-   * <p>
+   *
    * Valid Transitions:
-   * <ul>
-   * <li>{@link #FLUSHED} if the data is removed in order to manage memory usage</li>
-   * <li>{@link #INVALID} if a source was modified in such a way as to invalidate the previous data</li>
-   * </ul>
+   *
+   * * [FLUSHED] if the data is removed in order to manage memory usage
+   * * [INVALID] if a source was modified in such a way as to invalidate the previous data
+   *
    */
   static final CacheState VALID = new CacheState('VALID', 4);
   static final List<CacheState> values = [ERROR, FLUSHED, IN_PROCESS, INVALID, VALID];
@@ -3405,7 +3398,7 @@
   String toString() => name;
 }
 /**
- * Instances of the class {@code ChangeNoticeImpl} represent a change to the analysis results
+ * Instances of the class `ChangeNoticeImpl` represent a change to the analysis results
  * associated with a given source.
  * @coverage dart.engine
  */
@@ -3417,19 +3410,19 @@
   Source _source;
 
   /**
-   * The fully resolved AST that changed as a result of the analysis, or {@code null} if the AST was
+   * The fully resolved AST that changed as a result of the analysis, or `null` if the AST was
    * not changed.
    */
   CompilationUnit _compilationUnit;
 
   /**
-   * The errors that changed as a result of the analysis, or {@code null} if errors were not
+   * The errors that changed as a result of the analysis, or `null` if errors were not
    * changed.
    */
   List<AnalysisError> _errors;
 
   /**
-   * The line information associated with the source, or {@code null} if errors were not changed.
+   * The line information associated with the source, or `null` if errors were not changed.
    */
   LineInfo _lineInfo;
 
@@ -3447,21 +3440,21 @@
   }
 
   /**
-   * Return the fully resolved AST that changed as a result of the analysis, or {@code null} if the
+   * Return the fully resolved AST that changed as a result of the analysis, or `null` if the
    * AST was not changed.
    * @return the fully resolved AST that changed as a result of the analysis
    */
   CompilationUnit get compilationUnit => _compilationUnit;
 
   /**
-   * Return the errors that changed as a result of the analysis, or {@code null} if errors were not
+   * Return the errors that changed as a result of the analysis, or `null` if errors were not
    * changed.
    * @return the errors that changed as a result of the analysis
    */
   List<AnalysisError> get errors => _errors;
 
   /**
-   * Return the line information associated with the source, or {@code null} if errors were not
+   * Return the line information associated with the source, or `null` if errors were not
    * changed.
    * @return the line information associated with the source
    */
@@ -3493,112 +3486,112 @@
   }
 }
 /**
- * Instances of the class {@code DelegatingAnalysisContextImpl} extend {@link AnalysisContextImplanalysis context} to delegate sources to the appropriate analysis context. For instance, if the
- * source is in a system library then the analysis context from the {@link DartSdk} is used.
+ * Instances of the class `DelegatingAnalysisContextImpl` extend [AnalysisContextImplanalysis context] to delegate sources to the appropriate analysis context. For instance, if the
+ * source is in a system library then the analysis context from the [DartSdk] is used.
  * @coverage dart.engine
  */
 class DelegatingAnalysisContextImpl extends AnalysisContextImpl {
 
   /**
-   * This references the {@link InternalAnalysisContext} held onto by the {@link DartSdk} which is
-   * used (instead of this {@link AnalysisContext}) for SDK sources. This field is set when
-   * #setSourceFactory(SourceFactory) is called, and references the analysis context in the{@link DartUriResolver} in the {@link SourceFactory}, this analysis context assumes that there
+   * This references the [InternalAnalysisContext] held onto by the [DartSdk] which is
+   * used (instead of this [AnalysisContext]) for SDK sources. This field is set when
+   * #setSourceFactory(SourceFactory) is called, and references the analysis context in the[DartUriResolver] in the [SourceFactory], this analysis context assumes that there
    * will be such a resolver.
    */
   InternalAnalysisContext _sdkAnalysisContext;
   void addSourceInfo(Source source, SourceEntry info) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       _sdkAnalysisContext.addSourceInfo(source, info);
     } else {
       super.addSourceInfo(source, info);
     }
   }
   List<AnalysisError> computeErrors(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.computeErrors(source);
     } else {
       return super.computeErrors(source);
     }
   }
   HtmlElement computeHtmlElement(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.computeHtmlElement(source);
     } else {
       return super.computeHtmlElement(source);
     }
   }
   SourceKind computeKindOf(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.computeKindOf(source);
     } else {
       return super.computeKindOf(source);
     }
   }
   LibraryElement computeLibraryElement(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.computeLibraryElement(source);
     } else {
       return super.computeLibraryElement(source);
     }
   }
   LineInfo computeLineInfo(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.computeLineInfo(source);
     } else {
       return super.computeLineInfo(source);
     }
   }
   CompilationUnit computeResolvableCompilationUnit(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.computeResolvableCompilationUnit(source);
     } else {
       return super.computeResolvableCompilationUnit(source);
     }
   }
   AnalysisErrorInfo getErrors(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.getErrors(source);
     } else {
       return super.getErrors(source);
     }
   }
   HtmlElement getHtmlElement(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.getHtmlElement(source);
     } else {
       return super.getHtmlElement(source);
     }
   }
   List<Source> getHtmlFilesReferencing(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.getHtmlFilesReferencing(source);
     } else {
       return super.getHtmlFilesReferencing(source);
     }
   }
   SourceKind getKindOf(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.getKindOf(source);
     } else {
       return super.getKindOf(source);
     }
   }
   List<Source> getLibrariesContaining(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.getLibrariesContaining(source);
     } else {
       return super.getLibrariesContaining(source);
     }
   }
   List<Source> getLibrariesDependingOn(Source librarySource) {
-    if (librarySource.isInSystemLibrary()) {
+    if (librarySource.isInSystemLibrary) {
       return _sdkAnalysisContext.getLibrariesDependingOn(librarySource);
     } else {
       return super.getLibrariesDependingOn(librarySource);
     }
   }
   LibraryElement getLibraryElement(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.getLibraryElement(source);
     } else {
       return super.getLibraryElement(source);
@@ -3606,7 +3599,7 @@
   }
   List<Source> get librarySources => ArrayUtils.addAll(super.librarySources, _sdkAnalysisContext.librarySources);
   LineInfo getLineInfo(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.getLineInfo(source);
     } else {
       return super.getLineInfo(source);
@@ -3614,56 +3607,56 @@
   }
   Namespace getPublicNamespace(LibraryElement library) {
     Source source = library.source;
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.getPublicNamespace(library);
     } else {
       return super.getPublicNamespace(library);
     }
   }
   Namespace getPublicNamespace2(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.getPublicNamespace2(source);
     } else {
       return super.getPublicNamespace2(source);
     }
   }
   CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) {
-    if (unitSource.isInSystemLibrary()) {
+    if (unitSource.isInSystemLibrary) {
       return _sdkAnalysisContext.getResolvedCompilationUnit(unitSource, library);
     } else {
       return super.getResolvedCompilationUnit(unitSource, library);
     }
   }
   CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource) {
-    if (unitSource.isInSystemLibrary()) {
+    if (unitSource.isInSystemLibrary) {
       return _sdkAnalysisContext.getResolvedCompilationUnit2(unitSource, librarySource);
     } else {
       return super.getResolvedCompilationUnit2(unitSource, librarySource);
     }
   }
   bool isClientLibrary(Source librarySource) {
-    if (librarySource.isInSystemLibrary()) {
+    if (librarySource.isInSystemLibrary) {
       return _sdkAnalysisContext.isClientLibrary(librarySource);
     } else {
       return super.isClientLibrary(librarySource);
     }
   }
   bool isServerLibrary(Source librarySource) {
-    if (librarySource.isInSystemLibrary()) {
+    if (librarySource.isInSystemLibrary) {
       return _sdkAnalysisContext.isServerLibrary(librarySource);
     } else {
       return super.isServerLibrary(librarySource);
     }
   }
   CompilationUnit parseCompilationUnit(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.parseCompilationUnit(source);
     } else {
       return super.parseCompilationUnit(source);
     }
   }
   HtmlUnit parseHtmlUnit(Source source) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.parseHtmlUnit(source);
     } else {
       return super.parseHtmlUnit(source);
@@ -3674,35 +3667,35 @@
       return;
     }
     Source source = new JavaIterator(elementMap.keys.toSet()).next();
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       _sdkAnalysisContext.recordLibraryElements(elementMap);
     } else {
       super.recordLibraryElements(elementMap);
     }
   }
   CompilationUnit resolveCompilationUnit(Source source, LibraryElement library) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       return _sdkAnalysisContext.resolveCompilationUnit(source, library);
     } else {
       return super.resolveCompilationUnit(source, library);
     }
   }
   CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) {
-    if (unitSource.isInSystemLibrary()) {
+    if (unitSource.isInSystemLibrary) {
       return _sdkAnalysisContext.resolveCompilationUnit2(unitSource, librarySource);
     } else {
       return super.resolveCompilationUnit2(unitSource, librarySource);
     }
   }
   HtmlUnit resolveHtmlUnit(Source unitSource) {
-    if (unitSource.isInSystemLibrary()) {
+    if (unitSource.isInSystemLibrary) {
       return _sdkAnalysisContext.resolveHtmlUnit(unitSource);
     } else {
       return super.resolveHtmlUnit(unitSource);
     }
   }
   void setContents(Source source, String contents) {
-    if (source.isInSystemLibrary()) {
+    if (source.isInSystemLibrary) {
       _sdkAnalysisContext.setContents(source, contents);
     } else {
       super.setContents(source, contents);
@@ -3723,7 +3716,7 @@
   }
 }
 /**
- * Instances of the class {@code InstrumentedAnalysisContextImpl} implement an{@link AnalysisContext analysis context} by recording instrumentation data and delegating to
+ * Instances of the class `InstrumentedAnalysisContextImpl` implement an[AnalysisContext analysis context] by recording instrumentation data and delegating to
  * another analysis context to do the non-instrumentation work.
  * @coverage dart.engine
  */
@@ -3749,7 +3742,7 @@
   InternalAnalysisContext _basis;
 
   /**
-   * Create a new {@link InstrumentedAnalysisContextImpl} which wraps a new{@link AnalysisContextImpl} as the basis context.
+   * Create a new [InstrumentedAnalysisContextImpl] which wraps a new[AnalysisContextImpl] as the basis context.
    */
   InstrumentedAnalysisContextImpl() {
     _jtd_constructor_183_impl();
@@ -3759,9 +3752,9 @@
   }
 
   /**
-   * Create a new {@link InstrumentedAnalysisContextImpl} with a specified basis context, aka the
+   * Create a new [InstrumentedAnalysisContextImpl] with a specified basis context, aka the
    * context to wrap and instrument.
-   * @param context some {@link InstrumentedAnalysisContext} to wrap and instrument
+   * @param context some [InstrumentedAnalysisContext] to wrap and instrument
    */
   InstrumentedAnalysisContextImpl.con1(InternalAnalysisContext context) {
     _jtd_constructor_184_impl(context);
@@ -3870,7 +3863,7 @@
   }
 
   /**
-   * @return the underlying {@link AnalysisContext}.
+   * @return the underlying [AnalysisContext].
    */
   AnalysisContext get basis => _basis;
   Element getElement(ElementLocation location) {
@@ -4195,7 +4188,7 @@
   }
 }
 /**
- * The interface {@code InternalAnalysisContext} defines additional behavior for an analysis context
+ * The interface `InternalAnalysisContext` defines additional behavior for an analysis context
  * that is required by internal users of the context.
  */
 abstract class InternalAnalysisContext implements AnalysisContext {
@@ -4253,7 +4246,7 @@
   void recordLibraryElements(Map<Source, LibraryElement> elementMap);
 }
 /**
- * Instances of the class {@code RecordingErrorListener} implement an error listener that will
+ * Instances of the class `RecordingErrorListener` implement an error listener that will
  * record the errors that are reported to it in a way that is appropriate for caching those errors
  * within an analysis context.
  * @coverage dart.engine
@@ -4261,7 +4254,7 @@
 class RecordingErrorListener implements AnalysisErrorListener {
 
   /**
-   * A HashMap of lists containing the errors that were collected, keyed by each {@link Source}.
+   * A HashMap of lists containing the errors that were collected, keyed by each [Source].
    */
   Map<Source, List<AnalysisError>> _errors = new Map<Source, List<AnalysisError>>();
 
@@ -4277,7 +4270,7 @@
 
   /**
    * Answer the errors collected by the listener.
-   * @return an array of errors (not {@code null}, contains no {@code null}s)
+   * @return an array of errors (not `null`, contains no `null`s)
    */
   List<AnalysisError> get errors {
     Iterable<MapEntry<Source, List<AnalysisError>>> entrySet = getMapEntrySet(_errors);
@@ -4293,10 +4286,10 @@
   }
 
   /**
-   * Answer the errors collected by the listener for some passed {@link Source}.
-   * @param source some {@link Source} for which the caller wants the set of {@link AnalysisError}s
+   * Answer the errors collected by the listener for some passed [Source].
+   * @param source some [Source] for which the caller wants the set of [AnalysisError]s
    * collected by this listener
-   * @return the errors collected by the listener for the passed {@link Source}
+   * @return the errors collected by the listener for the passed [Source]
    */
   List<AnalysisError> getErrors2(Source source) {
     List<AnalysisError> errorsForSource = _errors[source];
@@ -4317,7 +4310,7 @@
   }
 }
 /**
- * Instances of the class {@code ResolutionEraser} remove any resolution information from an AST
+ * Instances of the class `ResolutionEraser` remove any resolution information from an AST
  * structure when used to visit that structure.
  */
 class ResolutionEraser extends GeneralizingASTVisitor<Object> {
@@ -4388,7 +4381,7 @@
   }
 }
 /**
- * The interface {@code Logger} defines the behavior of objects that can be used to receive
+ * The interface `Logger` defines the behavior of objects that can be used to receive
  * information about errors within the analysis engine. Implementations usually write this
  * information to a file, but can also record the information for later use (such as during testing)
  * or even ignore the information.
@@ -4431,7 +4424,7 @@
   void logInformation2(String message, Exception exception);
 }
 /**
- * Implementation of {@link Logger} that does nothing.
+ * Implementation of [Logger] that does nothing.
  */
 class Logger_NullLogger implements Logger {
   void logError(String message) {
diff --git a/pkg/analyzer_experimental/lib/src/generated/error.dart b/pkg/analyzer_experimental/lib/src/generated/error.dart
index 6061cb0..a330e1e 100644
--- a/pkg/analyzer_experimental/lib/src/generated/error.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/error.dart
@@ -6,7 +6,7 @@
 import 'ast.dart' show ASTNode;
 import 'scanner.dart' show Token;
 /**
- * Instances of the enumeration {@code ErrorSeverity} represent the severity of an {@link ErrorCode}.
+ * Instances of the enumeration `ErrorSeverity` represent the severity of an [ErrorCode].
  * @coverage dart.engine.error
  */
 class ErrorSeverity implements Comparable<ErrorSeverity> {
@@ -24,7 +24,7 @@
   static final ErrorSeverity SUGGESTION = new ErrorSeverity('SUGGESTION', 1, "S", "suggestion");
 
   /**
-   * The severity representing a warning. Warnings can become errors if the {@code -Werror} command
+   * The severity representing a warning. Warnings can become errors if the `-Werror` command
    * line flag is specified.
    */
   static final ErrorSeverity WARNING = new ErrorSeverity('WARNING', 2, "W", "warning");
@@ -84,7 +84,7 @@
   String toString() => name;
 }
 /**
- * Instances of the class {@code AnalysisErrorWithProperties}
+ * Instances of the class `AnalysisErrorWithProperties`
  */
 class AnalysisErrorWithProperties extends AnalysisError {
 
@@ -122,7 +122,7 @@
   Object getProperty(ErrorProperty property) => _propertyMap[property];
 
   /**
-   * Set the value of the given property to the given value. Using a value of {@code null} will
+   * Set the value of the given property to the given value. Using a value of `null` will
    * effectively remove the property from this error.
    * @param property the property whose value is to be returned
    * @param value the new value of the given property
@@ -132,7 +132,7 @@
   }
 }
 /**
- * Instances of the class {@code ErrorReporter} wrap an error listener with utility methods used to
+ * Instances of the class `ErrorReporter` wrap an error listener with utility methods used to
  * create the errors being reported.
  * @coverage dart.engine.error
  */
@@ -217,7 +217,7 @@
   }
 
   /**
-   * Set the source to be used when reporting errors. Setting the source to {@code null} will cause
+   * Set the source to be used when reporting errors. Setting the source to `null` will cause
    * the default source to be used.
    * @param source the source to be used when reporting errors
    */
@@ -226,7 +226,7 @@
   }
 }
 /**
- * Instances of the class {@code AnalysisError} represent an error discovered during the analysis of
+ * Instances of the class `AnalysisError` represent an error discovered during the analysis of
  * some Dart code.
  * @see AnalysisErrorListener
  * @coverage dart.engine.error
@@ -239,13 +239,13 @@
   static List<AnalysisError> NO_ERRORS = new List<AnalysisError>(0);
 
   /**
-   * A {@link Comparator} that sorts by the name of the file that the {@link AnalysisError} was
+   * A [Comparator] that sorts by the name of the file that the [AnalysisError] was
    * found.
    */
   static Comparator<AnalysisError> FILE_COMPARATOR = (AnalysisError o1, AnalysisError o2) => o1.source.shortName.compareTo(o2.source.shortName);
 
   /**
-   * A {@link Comparator} that sorts error codes first by their severity (errors first, warnings
+   * A [Comparator] that sorts error codes first by their severity (errors first, warnings
    * second), and then by the the error code type.
    */
   static Comparator<AnalysisError> ERROR_CODE_COMPARATOR = (AnalysisError o1, AnalysisError o2) {
@@ -273,7 +273,7 @@
   String _message;
 
   /**
-   * The source in which the error occurred, or {@code null} if unknown.
+   * The source in which the error occurred, or `null` if unknown.
    */
   Source _source;
 
@@ -350,7 +350,7 @@
   int get offset => _offset;
 
   /**
-   * Return the value of the given property, or {@code null} if the given property is not defined
+   * Return the value of the given property, or `null` if the given property is not defined
    * for this error.
    * @param property the property whose value is to be returned
    * @return the value of the given property
@@ -358,7 +358,7 @@
   Object getProperty(ErrorProperty property) => null;
 
   /**
-   * Return the source in which the error occurred, or {@code null} if unknown.
+   * Return the source in which the error occurred, or `null` if unknown.
    * @return the source in which the error occurred
    */
   Source get source => _source;
@@ -389,12 +389,12 @@
   }
 }
 /**
- * The enumeration {@code ErrorProperty} defines the properties that can be associated with an{@link AnalysisError}.
+ * The enumeration `ErrorProperty` defines the properties that can be associated with an[AnalysisError].
  */
 class ErrorProperty implements Comparable<ErrorProperty> {
 
   /**
-   * A property whose value is an array of {@link ExecutableElement executable elements} that should
+   * A property whose value is an array of [ExecutableElement executable elements] that should
    * be but are not implemented by a concrete class.
    */
   static final ErrorProperty UNIMPLEMENTED_METHODS = new ErrorProperty('UNIMPLEMENTED_METHODS', 0);
@@ -412,8 +412,8 @@
   String toString() => name;
 }
 /**
- * The interface {@code ErrorCode} defines the behavior common to objects representing error codes
- * associated with {@link AnalysisError analysis errors}.
+ * The interface `ErrorCode` defines the behavior common to objects representing error codes
+ * associated with [AnalysisError analysis errors].
  * @coverage dart.engine.error
  */
 abstract class ErrorCode {
@@ -437,7 +437,7 @@
   ErrorType get type;
 }
 /**
- * Instances of the enumeration {@code ErrorType} represent the type of an {@link ErrorCode}.
+ * Instances of the enumeration `ErrorType` represent the type of an [ErrorCode].
  * @coverage dart.engine.error
  */
 class ErrorType implements Comparable<ErrorType> {
@@ -501,7 +501,7 @@
   String toString() => name;
 }
 /**
- * The enumeration {@code CompileTimeErrorCode} defines the error codes used for compile time
+ * The enumeration `CompileTimeErrorCode` defines the error codes used for compile time
  * errors. 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.
@@ -523,10 +523,10 @@
    * 14.1 Imports: If a name <i>N</i> is referenced by a library <i>L</i> and <i>N</i> is introduced
    * into the top level scope <i>L</i> by more than one import then:
    * <ol>
-   * <li>It is a static warning if <i>N</i> is used as a type annotation.
-   * <li>In checked mode, it is a dynamic error if <i>N</i> is used as a type annotation and
+   * * It is a static warning if <i>N</i> is used as a type annotation.
+   * * In checked mode, it is a dynamic error if <i>N</i> is used as a type annotation and
    * referenced during a subtype test.
-   * <li>Otherwise, it is a compile-time error.
+   * * Otherwise, it is a compile-time error.
    * </ol>
    * @param ambiguousElementName the name of the ambiguous element
    * @param firstLibraryName the name of the first library that the type is found
@@ -602,7 +602,7 @@
   /**
    * 7.6.3 Constant Constructors: It is a compile-time error if a constant constructor is declared
    * by a class that has a non-final instance variable.
-   * <p>
+   *
    * The above refers to both locally declared and inherited instance variables.
    */
   static final CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD = new CompileTimeErrorCode('CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD', 12, "Cannot define the 'const' constructor for a class with non-final fields");
@@ -611,7 +611,7 @@
    * 7.6.1 Generative Constructors: In checked mode, it is a dynamic type error if o is not
    * <b>null</b> and the interface of the class of <i>o</i> is not a subtype of the static type of
    * the field <i>v</i>.
-   * <p>
+   *
    * 12.11.2 Const: It is a compile-time error if evaluation of a constant object results in an
    * uncaught exception being thrown.
    * @param initializerType the name of the type of the initializer expression
@@ -696,7 +696,7 @@
   /**
    * 12.11.2 Const: It is a compile-time error if <i>T</i> is not a class accessible in the current
    * scope, optionally followed by type arguments.
-   * <p>
+   *
    * 12.11.2 Const: If <i>e</i> is of the form <i>const T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>,
    * x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip; x<sub>n+k</sub>: a<sub>n+k</sub>)</i> it is a
    * compile-time error if <i>T</i> is not a class accessible in the current scope, optionally
@@ -791,16 +791,16 @@
 
   /**
    * 12.2 Null: It is a compile-time error for a class to attempt to extend or implement Null.
-   * <p>
+   *
    * 12.3 Numbers: It is a compile-time error for a class to attempt to extend or implement int.
-   * <p>
+   *
    * 12.3 Numbers: It is a compile-time error for a class to attempt to extend or implement double.
-   * <p>
+   *
    * 12.3 Numbers: It is a compile-time error for any type other than the types int and double to
    * attempt to extend or implement num.
-   * <p>
+   *
    * 12.4 Booleans: It is a compile-time error for a class to attempt to extend or implement bool.
-   * <p>
+   *
    * 12.5 Strings: It is a compile-time error for a class to attempt to extend or implement String.
    * @param typeName the name of the type that cannot be extended
    * @see #IMPLEMENTS_DISALLOWED_CLASS
@@ -809,7 +809,7 @@
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m < h</i> or if <i>m > n</i>.
-   * <p>
+   *
    * 12.11.2 Const: It is a compile-time error if evaluation of a constant object results in an
    * uncaught exception being thrown.
    * @param requiredCount the maximum number of positional arguments
@@ -819,16 +819,16 @@
 
   /**
    * 12.2 Null: It is a compile-time error for a class to attempt to extend or implement Null.
-   * <p>
+   *
    * 12.3 Numbers: It is a compile-time error for a class to attempt to extend or implement int.
-   * <p>
+   *
    * 12.3 Numbers: It is a compile-time error for a class to attempt to extend or implement double.
-   * <p>
+   *
    * 12.3 Numbers: It is a compile-time error for any type other than the types int and double to
    * attempt to extend or implement num.
-   * <p>
+   *
    * 12.4 Booleans: It is a compile-time error for a class to attempt to extend or implement bool.
-   * <p>
+   *
    * 12.5 Strings: It is a compile-time error for a class to attempt to extend or implement String.
    * @param typeName the name of the type that cannot be implemented
    * @see #EXTENDS_DISALLOWED_CLASS
@@ -886,7 +886,7 @@
   /**
    * 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
    * only action is to invoke another generative constructor.
-   * <p>
+   *
    * 7.6.1 Generative Constructors: It is a compile-time error if an initializing formal is used by
    * a function other than a non-redirecting generative constructor.
    */
@@ -923,7 +923,7 @@
   /**
    * 7.6.1 Generative Constructors: Note that this is not in scope on the right hand side of an
    * initializer.
-   * <p>
+   *
    * 12.10 This: It is a compile-time error if this appears in a top-level function or variable
    * initializer, in a factory constructor, or in a static method or variable initializer, or in the
    * initializer of an instance variable.
@@ -1076,10 +1076,10 @@
   /**
    * 14.2 Exports: It is a compile-time error if the compilation unit found at the specified URI is
    * not a library declaration.
-   * <p>
+   *
    * 14.1 Imports: It is a compile-time error if the compilation unit found at the specified URI is
    * not a library declaration.
-   * <p>
+   *
    * 14.3 Parts: It is a compile time error if the contents of the URI are not a valid part
    * declaration.
    * @param uri the URI that is invalid
@@ -1090,7 +1090,7 @@
   /**
    * 13.13 Break: It is a compile-time error if no such statement <i>s<sub>E</sub></i> exists within
    * the innermost function in which <i>s<sub>b</sub></i> occurs.
-   * <p>
+   *
    * 13.14 Continue: It is a compile-time error if no such statement or case clause
    * <i>s<sub>E</sub></i> exists within the innermost function in which <i>s<sub>c</sub></i> occurs.
    * @param labelName the name of the unresolvable label
@@ -1100,7 +1100,7 @@
   /**
    * 13.13 Break: It is a compile-time error if no such statement <i>s<sub>E</sub></i> exists within
    * the innermost function in which <i>s<sub>b</sub></i> occurs.
-   * <p>
+   *
    * 13.14 Continue: It is a compile-time error if no such statement or case clause
    * <i>s<sub>E</sub></i> exists within the innermost function in which <i>s<sub>c</sub></i> occurs.
    * @param labelName the name of the unresolvable label
@@ -1231,7 +1231,7 @@
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m < h</i> or if <i>m > n</i>.
-   * <p>
+   *
    * 12.11.2 Const: It is a compile-time error if evaluation of a constant object results in an
    * uncaught exception being thrown.
    * @param requiredCount the expected number of required arguments
@@ -1285,10 +1285,10 @@
   /**
    * 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
    * only action is to invoke another generative constructor.
-   * <p>
+   *
    * TODO(scheglov) review this later, there are no explicit "it is a compile-time error" in
    * specification. But it was added to the co19 and there is same error for factories.
-   * <p>
+   *
    * https://code.google.com/p/dart/issues/detail?id=954
    */
   static final CompileTimeErrorCode RECURSIVE_CONSTRUCTOR_REDIRECT = new CompileTimeErrorCode('RECURSIVE_CONSTRUCTOR_REDIRECT', 103, "Cycle in redirecting generative constructors");
@@ -1308,9 +1308,9 @@
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
    * superinterface of itself.
-   * <p>
+   *
    * 8.1 Superinterfaces: It is a compile-time error if an interface is a superinterface of itself.
-   * <p>
+   *
    * 7.9 Superclasses: It is a compile-time error if a class <i>C</i> is a superclass of itself.
    * @param className the name of the class that implements itself recursively
    * @param strImplementsPath a string representation of the implements loop
@@ -1320,9 +1320,9 @@
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
    * superinterface of itself.
-   * <p>
+   *
    * 8.1 Superinterfaces: It is a compile-time error if an interface is a superinterface of itself.
-   * <p>
+   *
    * 7.9 Superclasses: It is a compile-time error if a class <i>C</i> is a superclass of itself.
    * @param className the name of the class that implements itself recursively
    */
@@ -1331,9 +1331,9 @@
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
    * superinterface of itself.
-   * <p>
+   *
    * 8.1 Superinterfaces: It is a compile-time error if an interface is a superinterface of itself.
-   * <p>
+   *
    * 7.9 Superclasses: It is a compile-time error if a class <i>C</i> is a superclass of itself.
    * @param className the name of the class that implements itself recursively
    */
@@ -1404,20 +1404,10 @@
   static final CompileTimeErrorCode SUPER_INITIALIZER_IN_OBJECT = new CompileTimeErrorCode('SUPER_INITIALIZER_IN_OBJECT', 118, "");
 
   /**
-   * 12.11 Instance Creation: It is a compile-time error if a constructor of a non-generic type
-   * invoked by a new expression or a constant object expression is passed any type arguments.
-   * <p>
-   * 12.32 Type Cast: It is a compile-time error if <i>T</i> is a parameterized type of the form
-   * <i>G&lt;T<sub>1</sub>, &hellip;, T<sub>n</sub>&gt;</i> and <i>G</i> is not a generic type with
-   * <i>n</i> type parameters.
-   */
-  static final CompileTimeErrorCode TYPE_ARGUMENTS_FOR_NON_GENERIC_CLASS = new CompileTimeErrorCode('TYPE_ARGUMENTS_FOR_NON_GENERIC_CLASS', 119, "");
-
-  /**
    * 12.11.2 Const: It is a compile-time error if <i>T</i> is not a class accessible in the current
    * scope, optionally followed by type arguments.
    */
-  static final CompileTimeErrorCode UNDEFINED_CLASS = new CompileTimeErrorCode('UNDEFINED_CLASS', 120, "Undefined class '%s'");
+  static final CompileTimeErrorCode UNDEFINED_CLASS = new CompileTimeErrorCode('UNDEFINED_CLASS', 119, "Undefined class '%s'");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
@@ -1425,7 +1415,7 @@
    * a compile-time error if class <i>S</i> does not declare a generative constructor named <i>S</i>
    * (respectively <i>S.id</i>)
    */
-  static final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER = new CompileTimeErrorCode('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER', 121, "The class '%s' does not have a generative constructor '%s'");
+  static final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER = new CompileTimeErrorCode('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER', 120, "The class '%s' does not have a generative constructor '%s'");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
@@ -1433,7 +1423,7 @@
    * a compile-time error if class <i>S</i> does not declare a generative constructor named <i>S</i>
    * (respectively <i>S.id</i>)
    */
-  static final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = new CompileTimeErrorCode('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT', 122, "The class '%s' does not have a default generative constructor");
+  static final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = new CompileTimeErrorCode('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT', 121, "The class '%s' does not have a default generative constructor");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. Each final instance
@@ -1441,49 +1431,49 @@
    * <i>k</i>'s initializer list unless it has already been initialized by one of the following
    * means:
    * <ol>
-   * <li>Initialization at the declaration of <i>f</i>.
-   * <li>Initialization by means of an initializing formal of <i>k</i>.
+   * * Initialization at the declaration of <i>f</i>.
+   * * Initialization by means of an initializing formal of <i>k</i>.
    * </ol>
    * or a compile-time error occurs.
    */
-  static final CompileTimeErrorCode UNINITIALIZED_FINAL_FIELD = new CompileTimeErrorCode('UNINITIALIZED_FINAL_FIELD', 123, "");
+  static final CompileTimeErrorCode UNINITIALIZED_FINAL_FIELD = new CompileTimeErrorCode('UNINITIALIZED_FINAL_FIELD', 122, "");
 
   /**
    * 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub></i>, <i>1<=i<=l</i>,
    * must have a corresponding named parameter in the set {<i>p<sub>n+1</sub></i> ...
    * <i>p<sub>n+k</sub></i>} or a static warning occurs.
-   * <p>
+   *
    * 12.11.2 Const: It is a compile-time error if evaluation of a constant object results in an
    * uncaught exception being thrown.
    * @param name the name of the requested named parameter
    */
-  static final CompileTimeErrorCode UNDEFINED_NAMED_PARAMETER = new CompileTimeErrorCode('UNDEFINED_NAMED_PARAMETER', 124, "The named parameter '%s' is not defined");
+  static final CompileTimeErrorCode UNDEFINED_NAMED_PARAMETER = new CompileTimeErrorCode('UNDEFINED_NAMED_PARAMETER', 123, "The named parameter '%s' is not defined");
 
   /**
    * 14.2 Exports: It is a compile-time error if the compilation unit found at the specified URI is
    * not a library declaration.
-   * <p>
+   *
    * 14.1 Imports: It is a compile-time error if the compilation unit found at the specified URI is
    * not a library declaration.
-   * <p>
+   *
    * 14.3 Parts: It is a compile time error if the contents of the URI are not a valid part
    * declaration.
    * @param uri the URI pointing to a non-existent file
    * @see #INVALID_URI
    */
-  static final CompileTimeErrorCode URI_DOES_NOT_EXIST = new CompileTimeErrorCode('URI_DOES_NOT_EXIST', 125, "Target of URI does not exist: '%s'");
+  static final CompileTimeErrorCode URI_DOES_NOT_EXIST = new CompileTimeErrorCode('URI_DOES_NOT_EXIST', 124, "Target of URI does not exist: '%s'");
 
   /**
    * 14.1 Imports: It is a compile-time error if <i>x</i> is not a compile-time constant, or if
    * <i>x</i> involves string interpolation.
-   * <p>
+   *
    * 14.3 Parts: It is a compile-time error if <i>s</i> is not a compile-time constant, or if
    * <i>s</i> involves string interpolation.
-   * <p>
+   *
    * 14.5 URIs: It is a compile-time error if the string literal <i>x</i> that describes a URI is
    * not a compile-time constant, or if <i>x</i> involves string interpolation.
    */
-  static final CompileTimeErrorCode URI_WITH_INTERPOLATION = new CompileTimeErrorCode('URI_WITH_INTERPOLATION', 126, "URIs cannot use string interpolation");
+  static final CompileTimeErrorCode URI_WITH_INTERPOLATION = new CompileTimeErrorCode('URI_WITH_INTERPOLATION', 125, "URIs cannot use string interpolation");
 
   /**
    * 7.1.1 Operators: It is a compile-time error if the arity of the user-declared operator \[\]= is
@@ -1495,33 +1485,33 @@
    * @param expectedNumberOfParameters the number of parameters expected
    * @param actualNumberOfParameters the number of parameters found in the operator declaration
    */
-  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR = new CompileTimeErrorCode('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR', 127, "Operator '%s' should declare exactly %d parameter(s), but %d found");
+  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR = new CompileTimeErrorCode('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR', 126, "Operator '%s' should declare exactly %d parameter(s), but %d found");
 
   /**
    * 7.1.1 Operators: It is a compile time error if the arity of the user-declared operator - is not
    * 0 or 1.
    * @param actualNumberOfParameters the number of parameters found in the operator declaration
    */
-  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS = new CompileTimeErrorCode('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS', 128, "Operator '-' should declare 0 or 1 parameter, but %d found");
+  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS = new CompileTimeErrorCode('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS', 127, "Operator '-' should declare 0 or 1 parameter, but %d found");
 
   /**
    * 7.3 Setters: It is a compile-time error if a setter's formal parameter list does not include
    * exactly one required formal parameter <i>p</i>.
    * @param numberOfParameters the number of parameters found in the setter
    */
-  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER = new CompileTimeErrorCode('WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER', 129, "Setters should declare exactly one parameter, %d found");
+  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER = new CompileTimeErrorCode('WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER', 128, "Setters should declare exactly one parameter, %d found");
 
   /**
    * 12.11 Instance Creation: It is a compile-time error if a constructor of a generic type with
    * <i>n</i> type parameters invoked by a new expression or a constant object expression is passed
    * <i>m</i> type arguments where <i>m != n</i>.
-   * <p>
+   *
    * 12.31 Type Test: It is a compile-time error if <i>T</i> is a parameterized type of the form
    * <i>G&lt;T<sub>1</sub>, &hellip;, T<sub>n</sub>&gt;</i> and <i>G</i> is not a generic type with
    * <i>n</i> type parameters.
    */
-  static final CompileTimeErrorCode WRONG_NUMBER_OF_TYPE_ARGUMENTS = new CompileTimeErrorCode('WRONG_NUMBER_OF_TYPE_ARGUMENTS', 130, "");
-  static final List<CompileTimeErrorCode> values = [AMBIGUOUS_EXPORT, AMBIGUOUS_IMPORT, ARGUMENT_DEFINITION_TEST_NON_PARAMETER, BUILT_IN_IDENTIFIER_AS_TYPE, BUILT_IN_IDENTIFIER_AS_TYPE_NAME, BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, COMPILE_TIME_CONSTANT_RAISES_EXCEPTION, CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, CONST_CONSTRUCTOR_THROWS_EXCEPTION, CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE, CONST_FORMAL_PARAMETER, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, CONST_INSTANCE_FIELD, CONST_EVAL_TYPE_BOOL, CONST_EVAL_TYPE_BOOL_NUM_STRING, CONST_EVAL_TYPE_INT, CONST_EVAL_TYPE_NUM, CONST_EVAL_THROWS_EXCEPTION, CONST_WITH_INVALID_TYPE_PARAMETERS, CONST_WITH_NON_CONST, CONST_WITH_NON_CONSTANT_ARGUMENT, CONST_WITH_NON_TYPE, CONST_WITH_TYPE_PARAMETERS, CONST_WITH_UNDEFINED_CONSTRUCTOR, CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, DUPLICATE_CONSTRUCTOR_DEFAULT, DUPLICATE_CONSTRUCTOR_NAME, DUPLICATE_DEFINITION, DUPLICATE_MEMBER_NAME, DUPLICATE_MEMBER_NAME_INSTANCE_STATIC, DUPLICATE_NAMED_ARGUMENT, EXPORT_INTERNAL_LIBRARY, EXPORT_OF_NON_LIBRARY, EXTENDS_NON_CLASS, EXTENDS_DISALLOWED_CLASS, EXTRA_POSITIONAL_ARGUMENTS, IMPLEMENTS_DISALLOWED_CLASS, FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS, FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION, FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER, FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR, FINAL_INITIALIZED_MULTIPLE_TIMES, FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, GETTER_AND_METHOD_WITH_SAME_NAME, IMPLEMENTS_DYNAMIC, IMPLEMENTS_NON_CLASS, IMPLEMENTS_REPEATED, IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, IMPORT_INTERNAL_LIBRARY, IMPORT_OF_NON_LIBRARY, INCONSISTENT_CASE_EXPRESSION_TYPES, INITIALIZER_FOR_NON_EXISTANT_FIELD, INITIALIZER_FOR_STATIC_FIELD, INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, INITIALIZING_FORMAL_FOR_STATIC_FIELD, INVALID_CONSTANT, INVALID_CONSTRUCTOR_NAME, INVALID_FACTORY_NAME_NOT_A_CLASS, INVALID_OVERRIDE_DEFAULT_VALUE, INVALID_OVERRIDE_NAMED, INVALID_OVERRIDE_POSITIONAL, INVALID_OVERRIDE_REQUIRED, INVALID_REFERENCE_TO_THIS, INVALID_TYPE_ARGUMENT_FOR_KEY, INVALID_TYPE_ARGUMENT_IN_CONST_LIST, INVALID_TYPE_ARGUMENT_IN_CONST_MAP, INVALID_URI, LABEL_IN_OUTER_SCOPE, LABEL_UNDEFINED, MEMBER_WITH_CLASS_NAME, METHOD_AND_GETTER_WITH_SAME_NAME, MISSING_CONST_IN_LIST_LITERAL, MISSING_CONST_IN_MAP_LITERAL, MIXIN_DECLARES_CONSTRUCTOR, MIXIN_INHERITS_FROM_NOT_OBJECT, MIXIN_OF_NON_CLASS, MIXIN_REFERENCES_SUPER, MIXIN_WITH_NON_CLASS_SUPERCLASS, MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS, MULTIPLE_SUPER_INITIALIZERS, NEW_WITH_INVALID_TYPE_PARAMETERS, NON_CONST_MAP_AS_EXPRESSION_STATEMENT, NON_CONSTANT_CASE_EXPRESSION, NON_CONSTANT_DEFAULT_VALUE, NON_CONSTANT_LIST_ELEMENT, NON_CONSTANT_MAP_KEY, NON_CONSTANT_MAP_VALUE, NON_CONSTANT_VALUE_IN_INITIALIZER, NOT_ENOUGH_REQUIRED_ARGUMENTS, NON_GENERATIVE_CONSTRUCTOR, OBJECT_CANNOT_EXTEND_ANOTHER_CLASS, OPTIONAL_PARAMETER_IN_OPERATOR, PART_OF_NON_PART, PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, PRIVATE_OPTIONAL_PARAMETER, RECURSIVE_COMPILE_TIME_CONSTANT, RECURSIVE_CONSTRUCTOR_REDIRECT, RECURSIVE_FACTORY_REDIRECT, RECURSIVE_FUNCTION_TYPE_ALIAS, RECURSIVE_INTERFACE_INHERITANCE, RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS, RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS, REDIRECT_TO_NON_CONST_CONSTRUCTOR, REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER, RESERVED_WORD_AS_IDENTIFIER, RETHROW_OUTSIDE_CATCH, RETURN_IN_GENERATIVE_CONSTRUCTOR, STATIC_TOP_LEVEL_FUNCTION, STATIC_TOP_LEVEL_VARIABLE, SUPER_IN_INVALID_CONTEXT, SUPER_IN_REDIRECTING_CONSTRUCTOR, SUPER_INITIALIZER_IN_OBJECT, TYPE_ARGUMENTS_FOR_NON_GENERIC_CLASS, UNDEFINED_CLASS, UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, UNINITIALIZED_FINAL_FIELD, UNDEFINED_NAMED_PARAMETER, URI_DOES_NOT_EXIST, URI_WITH_INTERPOLATION, WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR, WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS, WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, WRONG_NUMBER_OF_TYPE_ARGUMENTS];
+  static final CompileTimeErrorCode WRONG_NUMBER_OF_TYPE_ARGUMENTS = new CompileTimeErrorCode('WRONG_NUMBER_OF_TYPE_ARGUMENTS', 129, "");
+  static final List<CompileTimeErrorCode> values = [AMBIGUOUS_EXPORT, AMBIGUOUS_IMPORT, ARGUMENT_DEFINITION_TEST_NON_PARAMETER, BUILT_IN_IDENTIFIER_AS_TYPE, BUILT_IN_IDENTIFIER_AS_TYPE_NAME, BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, COMPILE_TIME_CONSTANT_RAISES_EXCEPTION, CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, CONST_CONSTRUCTOR_THROWS_EXCEPTION, CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE, CONST_FORMAL_PARAMETER, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, CONST_INSTANCE_FIELD, CONST_EVAL_TYPE_BOOL, CONST_EVAL_TYPE_BOOL_NUM_STRING, CONST_EVAL_TYPE_INT, CONST_EVAL_TYPE_NUM, CONST_EVAL_THROWS_EXCEPTION, CONST_WITH_INVALID_TYPE_PARAMETERS, CONST_WITH_NON_CONST, CONST_WITH_NON_CONSTANT_ARGUMENT, CONST_WITH_NON_TYPE, CONST_WITH_TYPE_PARAMETERS, CONST_WITH_UNDEFINED_CONSTRUCTOR, CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, DUPLICATE_CONSTRUCTOR_DEFAULT, DUPLICATE_CONSTRUCTOR_NAME, DUPLICATE_DEFINITION, DUPLICATE_MEMBER_NAME, DUPLICATE_MEMBER_NAME_INSTANCE_STATIC, DUPLICATE_NAMED_ARGUMENT, EXPORT_INTERNAL_LIBRARY, EXPORT_OF_NON_LIBRARY, EXTENDS_NON_CLASS, EXTENDS_DISALLOWED_CLASS, EXTRA_POSITIONAL_ARGUMENTS, IMPLEMENTS_DISALLOWED_CLASS, FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS, FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION, FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER, FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR, FINAL_INITIALIZED_MULTIPLE_TIMES, FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, GETTER_AND_METHOD_WITH_SAME_NAME, IMPLEMENTS_DYNAMIC, IMPLEMENTS_NON_CLASS, IMPLEMENTS_REPEATED, IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, IMPORT_INTERNAL_LIBRARY, IMPORT_OF_NON_LIBRARY, INCONSISTENT_CASE_EXPRESSION_TYPES, INITIALIZER_FOR_NON_EXISTANT_FIELD, INITIALIZER_FOR_STATIC_FIELD, INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, INITIALIZING_FORMAL_FOR_STATIC_FIELD, INVALID_CONSTANT, INVALID_CONSTRUCTOR_NAME, INVALID_FACTORY_NAME_NOT_A_CLASS, INVALID_OVERRIDE_DEFAULT_VALUE, INVALID_OVERRIDE_NAMED, INVALID_OVERRIDE_POSITIONAL, INVALID_OVERRIDE_REQUIRED, INVALID_REFERENCE_TO_THIS, INVALID_TYPE_ARGUMENT_FOR_KEY, INVALID_TYPE_ARGUMENT_IN_CONST_LIST, INVALID_TYPE_ARGUMENT_IN_CONST_MAP, INVALID_URI, LABEL_IN_OUTER_SCOPE, LABEL_UNDEFINED, MEMBER_WITH_CLASS_NAME, METHOD_AND_GETTER_WITH_SAME_NAME, MISSING_CONST_IN_LIST_LITERAL, MISSING_CONST_IN_MAP_LITERAL, MIXIN_DECLARES_CONSTRUCTOR, MIXIN_INHERITS_FROM_NOT_OBJECT, MIXIN_OF_NON_CLASS, MIXIN_REFERENCES_SUPER, MIXIN_WITH_NON_CLASS_SUPERCLASS, MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS, MULTIPLE_SUPER_INITIALIZERS, NEW_WITH_INVALID_TYPE_PARAMETERS, NON_CONST_MAP_AS_EXPRESSION_STATEMENT, NON_CONSTANT_CASE_EXPRESSION, NON_CONSTANT_DEFAULT_VALUE, NON_CONSTANT_LIST_ELEMENT, NON_CONSTANT_MAP_KEY, NON_CONSTANT_MAP_VALUE, NON_CONSTANT_VALUE_IN_INITIALIZER, NOT_ENOUGH_REQUIRED_ARGUMENTS, NON_GENERATIVE_CONSTRUCTOR, OBJECT_CANNOT_EXTEND_ANOTHER_CLASS, OPTIONAL_PARAMETER_IN_OPERATOR, PART_OF_NON_PART, PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, PRIVATE_OPTIONAL_PARAMETER, RECURSIVE_COMPILE_TIME_CONSTANT, RECURSIVE_CONSTRUCTOR_REDIRECT, RECURSIVE_FACTORY_REDIRECT, RECURSIVE_FUNCTION_TYPE_ALIAS, RECURSIVE_INTERFACE_INHERITANCE, RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS, RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS, REDIRECT_TO_NON_CONST_CONSTRUCTOR, REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER, RESERVED_WORD_AS_IDENTIFIER, RETHROW_OUTSIDE_CATCH, RETURN_IN_GENERATIVE_CONSTRUCTOR, STATIC_TOP_LEVEL_FUNCTION, STATIC_TOP_LEVEL_VARIABLE, SUPER_IN_INVALID_CONTEXT, SUPER_IN_REDIRECTING_CONSTRUCTOR, SUPER_INITIALIZER_IN_OBJECT, UNDEFINED_CLASS, UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, UNINITIALIZED_FINAL_FIELD, UNDEFINED_NAMED_PARAMETER, URI_DOES_NOT_EXIST, URI_WITH_INTERPOLATION, WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR, WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS, WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, WRONG_NUMBER_OF_TYPE_ARGUMENTS];
 
   /// The name of this enum constant, as declared in the enum declaration.
   final String name;
@@ -1549,7 +1539,7 @@
   String toString() => name;
 }
 /**
- * The enumeration {@code PubSuggestionCode} defines the suggestions used for reporting deviations
+ * The enumeration `PubSuggestionCode` defines the suggestions used for reporting deviations
  * from pub best practices. The convention for this class is for the name of the bad practice to
  * indicate the problem that caused the suggestion to be generated and for the message to explain
  * what is wrong and, when appropriate, how the situation can be corrected.
@@ -1559,7 +1549,7 @@
   /**
    * It is a bad practice for a source file in a package "lib" directory hierarchy to traverse
    * outside that directory hierarchy. For example, a source file in the "lib" directory should not
-   * contain a directive such as {@code import '../web/some.dart'} which references a file outside
+   * contain a directive such as `import '../web/some.dart'` which references a file outside
    * the lib directory.
    */
   static final PubSuggestionCode FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE = new PubSuggestionCode('FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE', 0, "A file in the 'lib' directory hierarchy should not reference a file outside that hierarchy");
@@ -1567,7 +1557,7 @@
   /**
    * It is a bad practice for a source file ouside a package "lib" directory hierarchy to traverse
    * into that directory hierarchy. For example, a source file in the "web" directory should not
-   * contain a directive such as {@code import '../lib/some.dart'} which references a file inside
+   * contain a directive such as `import '../lib/some.dart'` which references a file inside
    * the lib directory.
    */
   static final PubSuggestionCode FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE = new PubSuggestionCode('FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE', 1, "A file outside the 'lib' directory hierarchy should not reference a file inside that hierarchy. Use a package: reference instead.");
@@ -1575,7 +1565,7 @@
   /**
    * It is a bad practice for a package import to reference anything outside the given package, or
    * more generally, it is bad practice for a package import to contain a "..". For example, a
-   * source file should not contain a directive such as {@code import 'package:foo/../some.dart'}.
+   * source file should not contain a directive such as `import 'package:foo/../some.dart'`.
    */
   static final PubSuggestionCode PACKAGE_IMPORT_CONTAINS_DOT_DOT = new PubSuggestionCode('PACKAGE_IMPORT_CONTAINS_DOT_DOT', 2, "A package import should not contain '..'");
   static final List<PubSuggestionCode> values = [FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE, FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE, PACKAGE_IMPORT_CONTAINS_DOT_DOT];
@@ -1606,7 +1596,7 @@
   String toString() => name;
 }
 /**
- * The enumeration {@code StaticWarningCode} defines the error codes used for static warnings. The
+ * The enumeration `StaticWarningCode` defines the error codes used for static warnings. 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.
@@ -1618,10 +1608,10 @@
    * 14.1 Imports: If a name <i>N</i> is referenced by a library <i>L</i> and <i>N</i> is introduced
    * into the top level scope <i>L</i> by more than one import then:
    * <ol>
-   * <li>It is a static warning if <i>N</i> is used as a type annotation.
-   * <li>In checked mode, it is a dynamic error if <i>N</i> is used as a type annotation and
+   * * It is a static warning if <i>N</i> is used as a type annotation.
+   * * In checked mode, it is a dynamic error if <i>N</i> is used as a type annotation and
    * referenced during a subtype test.
-   * <li>Otherwise, it is a compile-time error.
+   * * Otherwise, it is a compile-time error.
    * </ol>
    * @param ambiguousTypeName the name of the ambiguous type
    * @param firstLibraryName the name of the first library that the type is found
@@ -1633,17 +1623,17 @@
    * 12.11.1 New: It is a static warning if the static type of <i>a<sub>i</sub>, 1 &lt;= i &lt;= n+
    * k</i> may not be assigned to the type of the corresponding formal parameter of the constructor
    * <i>T.id</i> (respectively <i>T</i>).
-   * <p>
+   *
    * 12.11.2 Const: It is a static warning if the static type of <i>a<sub>i</sub>, 1 &lt;= i &lt;=
    * n+ k</i> may not be assigned to the type of the corresponding formal parameter of the
    * constructor <i>T.id</i> (respectively <i>T</i>).
-   * <p>
+   *
    * 12.14.2 Binding Actuals to Formals: Let <i>T<sub>i</sub></i> be the static type of
    * <i>a<sub>i</sub></i>, let <i>S<sub>i</sub></i> be the type of <i>p<sub>i</sub>, 1 &lt;= i &lt;=
    * n+k</i> and let <i>S<sub>q</sub></i> be the type of the named parameter <i>q</i> of <i>f</i>.
    * It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 &lt;=
    * j &lt;= m</i>.
-   * <p>
+   *
    * 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub>, 1 &lt;= i &lt;= l</i>,
    * must have a corresponding named parameter in the set <i>{p<sub>n+1</sub>, &hellip;
    * p<sub>n+k</sub>}</i> or a static warning occurs. It is a static warning if
@@ -1774,7 +1764,7 @@
    * <i>e</i> proceeds as follows: First, the expression <i>e</i> is evaluated to an object
    * <i>o</i>. Then, the instance variable <i>v</i> of the object denoted by this is bound to
    * <i>o</i>.
-   * <p>
+   *
    * 12.14.2 Binding Actuals to Formals: Let <i>T<sub>i</sub></i> be the static type of
    * <i>a<sub>i</sub></i>, let <i>S<sub>i</sub></i> be the type of <i>p<sub>i</sub>, 1 &lt;= i &lt;=
    * n+k</i> and let <i>S<sub>q</sub></i> be the type of the named parameter <i>q</i> of <i>f</i>.
@@ -1813,7 +1803,7 @@
    * &hellip; m<sub>k</sub></i> with the same name <i>n</i> that would be inherited (because
    * identically named members existed in several superinterfaces) then at most one member is
    * inherited.
-   * <p>
+   *
    * If some but not all of the <i>m<sub>i</sub>, 1 &lt;= i &lt;= k</i>, are getters, or if some but
    * not all of the <i>m<sub>i</sub></i> are setters, none of the <i>m<sub>i</sub></i> are
    * inherited, and a static warning is issued.
@@ -1899,7 +1889,15 @@
    * a formal parameter <i>p</i> and the signature of <i>m1</i> specifies a different default value
    * for <i>p</i>.
    */
-  static final StaticWarningCode INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES = new StaticWarningCode('INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES', 32, "");
+  static final StaticWarningCode INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED = new StaticWarningCode('INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED', 32, "Parameters cannot override default values, this method overrides '%s.%s' where '%s' has a different value");
+
+  /**
+   * 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
+   * instance member <i>m2</i>, the signature of <i>m2</i> explicitly specifies a default value for
+   * a formal parameter <i>p</i> and the signature of <i>m1</i> specifies a different default value
+   * for <i>p</i>.
+   */
+  static final StaticWarningCode INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL = new StaticWarningCode('INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL', 33, "Parameters cannot override default values, this method overrides '%s.%s' where this positional parameter has a different value");
 
   /**
    * 7.3 Setters: It is a static warning if a setter <i>m1</i> overrides a setter <i>m2</i> and the
@@ -1910,7 +1908,7 @@
    * @param className the name of the class where the overridden setter is declared
    * @see #INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
    */
-  static final StaticWarningCode INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE = new StaticWarningCode('INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE', 33, "The parameter type '%s' is not assignable to '%s' as required by the setter it is overriding from '%s'");
+  static final StaticWarningCode INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE = new StaticWarningCode('INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE', 34, "The parameter type '%s' is not assignable to '%s' as required by the setter it is overriding from '%s'");
 
   /**
    * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
@@ -1918,27 +1916,27 @@
    * x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. If <i>S.m</i> exists, it is a static warning if the type
    * <i>F</i> of <i>S.m</i> may not be assigned to a function type.
    */
-  static final StaticWarningCode INVOCATION_OF_NON_FUNCTION = new StaticWarningCode('INVOCATION_OF_NON_FUNCTION', 34, "");
+  static final StaticWarningCode INVOCATION_OF_NON_FUNCTION = new StaticWarningCode('INVOCATION_OF_NON_FUNCTION', 35, "");
 
   /**
    * 7.3 Setters: It is a static warning if a class has a setter named <i>v=</i> with argument type
    * <i>T</i> and a getter named <i>v</i> with return type <i>S</i>, and <i>T</i> may not be
    * assigned to <i>S</i>.
    */
-  static final StaticWarningCode MISMATCHED_GETTER_AND_SETTER_TYPES = new StaticWarningCode('MISMATCHED_GETTER_AND_SETTER_TYPES', 35, "The parameter type for setter '%s' is %s which is not assignable to its getter (of type %s)");
+  static final StaticWarningCode MISMATCHED_GETTER_AND_SETTER_TYPES = new StaticWarningCode('MISMATCHED_GETTER_AND_SETTER_TYPES', 36, "The parameter type for setter '%s' is %s which is not assignable to its getter (of type %s)");
 
   /**
    * 12.11.1 New: It is a static warning if <i>q</i> is a constructor of an abstract class and
    * <i>q</i> is not a factory constructor.
    */
-  static final StaticWarningCode NEW_WITH_ABSTRACT_CLASS = new StaticWarningCode('NEW_WITH_ABSTRACT_CLASS', 36, "Abstract classes cannot be created with a 'new' expression");
+  static final StaticWarningCode NEW_WITH_ABSTRACT_CLASS = new StaticWarningCode('NEW_WITH_ABSTRACT_CLASS', 37, "Abstract classes cannot be created with a 'new' expression");
 
   /**
    * 12.11.1 New: It is a static warning if <i>T</i> is not a class accessible in the current scope,
    * optionally followed by type arguments.
    * @param name the name of the non-type element
    */
-  static final StaticWarningCode NEW_WITH_NON_TYPE = new StaticWarningCode('NEW_WITH_NON_TYPE', 37, "The name '%s' is not a class");
+  static final StaticWarningCode NEW_WITH_NON_TYPE = new StaticWarningCode('NEW_WITH_NON_TYPE', 38, "The name '%s' is not a class");
 
   /**
    * 12.11.1 New: If <i>T</i> is a class or parameterized type accessible in the current scope then:
@@ -1949,7 +1947,7 @@
    * a<sub>n+1</sub>, &hellip; x<sub>n+k</sub>: a<sub>n+kM/sub>)</i> it is a static warning if the
    * type <i>T</i> does not declare a constructor with the same name as the declaration of <i>T</i>.
    */
-  static final StaticWarningCode NEW_WITH_UNDEFINED_CONSTRUCTOR = new StaticWarningCode('NEW_WITH_UNDEFINED_CONSTRUCTOR', 38, "The class '%s' does not have a constructor '%s'");
+  static final StaticWarningCode NEW_WITH_UNDEFINED_CONSTRUCTOR = new StaticWarningCode('NEW_WITH_UNDEFINED_CONSTRUCTOR', 39, "The class '%s' does not have a constructor '%s'");
 
   /**
    * 12.11.1 New: If <i>T</i> is a class or parameterized type accessible in the current scope then:
@@ -1960,12 +1958,25 @@
    * a<sub>n+1</sub>, &hellip; x<sub>n+k</sub>: a<sub>n+kM/sub>)</i> it is a static warning if the
    * type <i>T</i> does not declare a constructor with the same name as the declaration of <i>T</i>.
    */
-  static final StaticWarningCode NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT = new StaticWarningCode('NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT', 39, "The class '%s' does not have a default constructor");
+  static final StaticWarningCode NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT = new StaticWarningCode('NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT', 40, "The class '%s' does not have a default constructor");
+
+  /**
+   * 7.6.1 Generative Constructors: If no superinitializer is provided, an implicit superinitializer
+   * of the form <b>super</b>() is added at the end of <i>k</i>'s initializer list, unless the
+   * enclosing class is class <i>Object</i>.
+   */
+  static final StaticWarningCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT = new StaticWarningCode('NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT', 41, "The class '%s' does not have a default constructor");
+
+  /**
+   * 7.6 Constructors: Iff no constructor is specified for a class <i>C</i>, it implicitly has a
+   * default constructor C() : <b>super<b>() {}, unless <i>C</i> is class <i>Object</i>.
+   */
+  static final StaticWarningCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT = new StaticWarningCode('NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT', 42, "The class '%s' does not have a default constructor");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an
    * abstract method.
-   * <p>
+   *
    * 7.10 Superinterfaces: It is a static warning if the implicit interface of a non-abstract class
    * <i>C</i> includes an instance member <i>m</i> and <i>C</i> does not declare or inherit a
    * corresponding instance member <i>m</i>.
@@ -1987,12 +1998,12 @@
    * @param name fourth member name
    * @param additionalCount the number of additional missing members that aren't listed
    */
-  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS = new StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS', 40, "Missing inherited members: %s'%s.%s', %s'%s.%s', %s'%s.%s', %s'%s.%s' and %d more");
+  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS = new StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS', 43, "Missing inherited members: %s'%s.%s', %s'%s.%s', %s'%s.%s', %s'%s.%s' and %d more");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an
    * abstract method.
-   * <p>
+   *
    * 7.10 Superinterfaces: It is a static warning if the implicit interface of a non-abstract class
    * <i>C</i> includes an instance member <i>m</i> and <i>C</i> does not declare or inherit a
    * corresponding instance member <i>m</i>.
@@ -2013,12 +2024,12 @@
    * @param enclosingClass enclosing class of the fourth missing member
    * @param name fourth member name
    */
-  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR = new StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR', 41, "Missing inherited members: %s'%s.%s', %s'%s.%s', %s'%s.%s' and %s'%s.%s'");
+  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR = new StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR', 44, "Missing inherited members: %s'%s.%s', %s'%s.%s', %s'%s.%s' and %s'%s.%s'");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an
    * abstract method.
-   * <p>
+   *
    * 7.10 Superinterfaces: It is a static warning if the implicit interface of a non-abstract class
    * <i>C</i> includes an instance member <i>m</i> and <i>C</i> does not declare or inherit a
    * corresponding instance member <i>m</i>.
@@ -2026,12 +2037,12 @@
    * @param enclosingClass enclosing class of the missing member
    * @param name member name
    */
-  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE = new StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE', 42, "Missing inherited member %s'%s.%s'");
+  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE = new StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE', 45, "Missing inherited member %s'%s.%s'");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an
    * abstract method.
-   * <p>
+   *
    * 7.10 Superinterfaces: It is a static warning if the implicit interface of a non-abstract class
    * <i>C</i> includes an instance member <i>m</i> and <i>C</i> does not declare or inherit a
    * corresponding instance member <i>m</i>.
@@ -2048,12 +2059,12 @@
    * @param enclosingClass enclosing class of the third missing member
    * @param name third member name
    */
-  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE = new StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE', 43, "Missing inherited members: %s'%s.%s', %s'%s.%s' and %s'%s.%s'");
+  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE = new StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE', 46, "Missing inherited members: %s'%s.%s', %s'%s.%s' and %s'%s.%s'");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an
    * abstract method.
-   * <p>
+   *
    * 7.10 Superinterfaces: It is a static warning if the implicit interface of a non-abstract class
    * <i>C</i> includes an instance member <i>m</i> and <i>C</i> does not declare or inherit a
    * corresponding instance member <i>m</i>.
@@ -2066,7 +2077,7 @@
    * @param enclosingClass enclosing class of the second missing member
    * @param name second member name
    */
-  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO = new StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO', 44, "Missing inherited members: %s'%s.%s' and %s'%s.%s'");
+  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO = new StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO', 47, "Missing inherited members: %s'%s.%s' and %s'%s.%s'");
 
   /**
    * 13.11 Try: An on-catch clause of the form <i>on T catch (p<sub>1</sub>, p<sub>2</sub>) s</i> or
@@ -2075,38 +2086,38 @@
    * catch clause.
    * @param name the name of the non-type element
    */
-  static final StaticWarningCode NON_TYPE_IN_CATCH_CLAUSE = new StaticWarningCode('NON_TYPE_IN_CATCH_CLAUSE', 45, "The name '%s' is not a type and cannot be used in an on-catch clause");
+  static final StaticWarningCode NON_TYPE_IN_CATCH_CLAUSE = new StaticWarningCode('NON_TYPE_IN_CATCH_CLAUSE', 48, "The name '%s' is not a type and cannot be used in an on-catch clause");
 
   /**
    * 7.1.1 Operators: It is a static warning if the return type of the user-declared operator \[\]= is
    * explicitly declared and not void.
    */
-  static final StaticWarningCode NON_VOID_RETURN_FOR_OPERATOR = new StaticWarningCode('NON_VOID_RETURN_FOR_OPERATOR', 46, "The return type of the operator []= must be 'void'");
+  static final StaticWarningCode NON_VOID_RETURN_FOR_OPERATOR = new StaticWarningCode('NON_VOID_RETURN_FOR_OPERATOR', 49, "The return type of the operator []= must be 'void'");
 
   /**
    * 7.3 Setters: It is a static warning if a setter declares a return type other than void.
    */
-  static final StaticWarningCode NON_VOID_RETURN_FOR_SETTER = new StaticWarningCode('NON_VOID_RETURN_FOR_SETTER', 47, "The return type of the setter must be 'void'");
+  static final StaticWarningCode NON_VOID_RETURN_FOR_SETTER = new StaticWarningCode('NON_VOID_RETURN_FOR_SETTER', 50, "The return type of the setter must be 'void'");
 
   /**
-   * 15.1 Static Types: A type <i>T</i> is malformed iff: <li><i>T</i> has the form <i>id</i> or the
+   * 15.1 Static Types: A type <i>T</i> is malformed iff: * <i>T</i> has the form <i>id</i> or the
    * form <i>prefix.id</i>, and in the enclosing lexical scope, the name <i>id</i> (respectively
-   * <i>prefix.id</i>) does not denote a type.</li> <li><i>T</i> denotes a type variable in the
-   * enclosing lexical scope, but occurs in the signature or body of a static member.</li> <li>
+   * <i>prefix.id</i>) does not denote a type. * <i>T</i> denotes a type variable in the
+   * enclosing lexical scope, but occurs in the signature or body of a static member. *
    * <i>T</i> is a parameterized type of the form <i>G&lt;S<sub>1</sub>, .., S<sub>n</sub>&gt;</i>,
-   * and <i>G</i> is malformed.</li></ul>
-   * <p>
+   * and <i>G</i> is malformed.
+   *
    * Any use of a malformed type gives rise to a static warning.
    * @param nonTypeName the name that is not a type
    */
-  static final StaticWarningCode NOT_A_TYPE = new StaticWarningCode('NOT_A_TYPE', 48, "%s is not a type");
+  static final StaticWarningCode NOT_A_TYPE = new StaticWarningCode('NOT_A_TYPE', 51, "%s is not a type");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m < h</i> or if <i>m > n</i>.
    * @param requiredCount the expected number of required arguments
    * @param argumentCount the actual number of positional arguments given
    */
-  static final StaticWarningCode NOT_ENOUGH_REQUIRED_ARGUMENTS = new StaticWarningCode('NOT_ENOUGH_REQUIRED_ARGUMENTS', 49, "%d required argument(s) expected, but %d found");
+  static final StaticWarningCode NOT_ENOUGH_REQUIRED_ARGUMENTS = new StaticWarningCode('NOT_ENOUGH_REQUIRED_ARGUMENTS', 52, "%d required argument(s) expected, but %d found");
 
   /**
    * 14.3 Parts: It is a static warning if the referenced part declaration <i>p</i> names a library
@@ -2114,7 +2125,7 @@
    * @param expectedLibraryName the name of expected library name
    * @param actualLibraryName the non-matching actual library name from the "part of" declaration
    */
-  static final StaticWarningCode PART_OF_DIFFERENT_LIBRARY = new StaticWarningCode('PART_OF_DIFFERENT_LIBRARY', 50, "Expected this library to be part of '%s', not '%s'");
+  static final StaticWarningCode PART_OF_DIFFERENT_LIBRARY = new StaticWarningCode('PART_OF_DIFFERENT_LIBRARY', 53, "Expected this library to be part of '%s', not '%s'");
 
   /**
    * 7.6.2 Factories: It is a static warning if the function type of <i>k'</i> is not a subtype of
@@ -2122,7 +2133,7 @@
    * @param redirectedName the name of the redirected constructor
    * @param redirectingName the name of the redirecting constructor
    */
-  static final StaticWarningCode REDIRECT_TO_INVALID_FUNCTION_TYPE = new StaticWarningCode('REDIRECT_TO_INVALID_FUNCTION_TYPE', 51, "The redirected constructor '%s' has incompatible parameters with '%s'");
+  static final StaticWarningCode REDIRECT_TO_INVALID_FUNCTION_TYPE = new StaticWarningCode('REDIRECT_TO_INVALID_FUNCTION_TYPE', 54, "The redirected constructor '%s' has incompatible parameters with '%s'");
 
   /**
    * 7.6.2 Factories: It is a static warning if the function type of <i>k'</i> is not a subtype of
@@ -2130,62 +2141,62 @@
    * @param redirectedName the name of the redirected constructor return type
    * @param redirectingName the name of the redirecting constructor return type
    */
-  static final StaticWarningCode REDIRECT_TO_INVALID_RETURN_TYPE = new StaticWarningCode('REDIRECT_TO_INVALID_RETURN_TYPE', 52, "The return type '%s' of the redirected constructor is not a subclass of '%s'");
+  static final StaticWarningCode REDIRECT_TO_INVALID_RETURN_TYPE = new StaticWarningCode('REDIRECT_TO_INVALID_RETURN_TYPE', 55, "The return type '%s' of the redirected constructor is not a subclass of '%s'");
 
   /**
    * 7.6.2 Factories: It is a static warning if type does not denote a class accessible in the
    * current scope; if type does denote such a class <i>C</i> it is a static warning if the
    * referenced constructor (be it <i>type</i> or <i>type.id</i>) is not a constructor of <i>C</i>.
    */
-  static final StaticWarningCode REDIRECT_TO_MISSING_CONSTRUCTOR = new StaticWarningCode('REDIRECT_TO_MISSING_CONSTRUCTOR', 53, "The constructor '%s' could not be found in '%s'");
+  static final StaticWarningCode REDIRECT_TO_MISSING_CONSTRUCTOR = new StaticWarningCode('REDIRECT_TO_MISSING_CONSTRUCTOR', 56, "The constructor '%s' could not be found in '%s'");
 
   /**
    * 7.6.2 Factories: It is a static warning if type does not denote a class accessible in the
    * current scope; if type does denote such a class <i>C</i> it is a static warning if the
    * referenced constructor (be it <i>type</i> or <i>type.id</i>) is not a constructor of <i>C</i>.
    */
-  static final StaticWarningCode REDIRECT_TO_NON_CLASS = new StaticWarningCode('REDIRECT_TO_NON_CLASS', 54, "The name '%s' is not a type and cannot be used in a redirected constructor");
+  static final StaticWarningCode REDIRECT_TO_NON_CLASS = new StaticWarningCode('REDIRECT_TO_NON_CLASS', 57, "The name '%s' is not a type and cannot be used in a redirected constructor");
 
   /**
    * 13.11 Return: Let <i>f</i> be the function immediately enclosing a return statement of the form
    * <i>return;</i> It is a static warning if both of the following conditions hold:
    * <ol>
-   * <li><i>f</i> is not a generative constructor.
-   * <li>The return type of <i>f</i> may not be assigned to void.
+   * * <i>f</i> is not a generative constructor.
+   * * The return type of <i>f</i> may not be assigned to void.
    * </ol>
    */
-  static final StaticWarningCode RETURN_WITHOUT_VALUE = new StaticWarningCode('RETURN_WITHOUT_VALUE', 55, "Missing return value after 'return'");
+  static final StaticWarningCode RETURN_WITHOUT_VALUE = new StaticWarningCode('RETURN_WITHOUT_VALUE', 58, "Missing return value after 'return'");
 
   /**
    * 12.15.3 Static Invocation: It is a static warning if <i>C</i> does not declare a static method
    * or getter <i>m</i>.
    * @param memberName the name of the instance member
    */
-  static final StaticWarningCode STATIC_ACCESS_TO_INSTANCE_MEMBER = new StaticWarningCode('STATIC_ACCESS_TO_INSTANCE_MEMBER', 56, "Instance member '%s' cannot be accessed using static access");
+  static final StaticWarningCode STATIC_ACCESS_TO_INSTANCE_MEMBER = new StaticWarningCode('STATIC_ACCESS_TO_INSTANCE_MEMBER', 59, "Instance member '%s' cannot be accessed using static access");
 
   /**
    * 13.9 Switch: It is a static warning if the type of <i>e</i> may not be assigned to the type of
    * <i>e<sub>k</sub></i>.
    */
-  static final StaticWarningCode SWITCH_EXPRESSION_NOT_ASSIGNABLE = new StaticWarningCode('SWITCH_EXPRESSION_NOT_ASSIGNABLE', 57, "Type '%s' of the switch expression is not assignable to the type '%s' of case expressions");
+  static final StaticWarningCode SWITCH_EXPRESSION_NOT_ASSIGNABLE = new StaticWarningCode('SWITCH_EXPRESSION_NOT_ASSIGNABLE', 60, "Type '%s' of the switch expression is not assignable to the type '%s' of case expressions");
 
   /**
    * 12.31 Type Test: It is a static warning if <i>T</i> does not denote a type available in the
    * current lexical scope.
    */
-  static final StaticWarningCode TYPE_TEST_NON_TYPE = new StaticWarningCode('TYPE_TEST_NON_TYPE', 58, "The name '%s' is not a type and cannot be used in an 'is' expression");
+  static final StaticWarningCode TYPE_TEST_NON_TYPE = new StaticWarningCode('TYPE_TEST_NON_TYPE', 61, "The name '%s' is not a type and cannot be used in an 'is' expression");
 
   /**
-   * 15.1 Static Types: A type <i>T</i> is malformed iff: <li><i>T</i> has the form <i>id</i> or the
+   * 15.1 Static Types: A type <i>T</i> is malformed iff: * <i>T</i> has the form <i>id</i> or the
    * form <i>prefix.id</i>, and in the enclosing lexical scope, the name <i>id</i> (respectively
-   * <i>prefix.id</i>) does not denote a type.</li> <li><i>T</i> denotes a type variable in the
-   * enclosing lexical scope, but occurs in the signature or body of a static member.</li> <li>
+   * <i>prefix.id</i>) does not denote a type. * <i>T</i> denotes a type variable in the
+   * enclosing lexical scope, but occurs in the signature or body of a static member. *
    * <i>T</i> is a parameterized type of the form <i>G&lt;S<sub>1</sub>, .., S<sub>n</sub>&gt;</i>,
-   * and <i>G</i> is malformed.</li></ul>
-   * <p>
+   * and <i>G</i> is malformed.
+   *
    * Any use of a malformed type gives rise to a static warning.
    */
-  static final StaticWarningCode TYPE_VARIABLE_IN_STATIC_SCOPE = new StaticWarningCode('TYPE_VARIABLE_IN_STATIC_SCOPE', 59, "");
+  static final StaticWarningCode TYPE_VARIABLE_IN_STATIC_SCOPE = new StaticWarningCode('TYPE_VARIABLE_IN_STATIC_SCOPE', 62, "");
 
   /**
    * 12.15.3 Static Invocation: A static method invocation <i>i</i> has the form
@@ -2193,12 +2204,12 @@
    * x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. It is a static warning if <i>C</i> does not denote a
    * class in the current scope.
    */
-  static final StaticWarningCode UNDEFINED_CLASS = new StaticWarningCode('UNDEFINED_CLASS', 60, "Undefined class '%s'");
+  static final StaticWarningCode UNDEFINED_CLASS = new StaticWarningCode('UNDEFINED_CLASS', 63, "Undefined class '%s'");
 
   /**
-   * Same as {@link #UNDEFINED_CLASS}, but to catch using "boolean" instead of "bool".
+   * Same as [UNDEFINED_CLASS], but to catch using "boolean" instead of "bool".
    */
-  static final StaticWarningCode UNDEFINED_CLASS_BOOLEAN = new StaticWarningCode('UNDEFINED_CLASS_BOOLEAN', 61, "Undefined class 'boolean'; did you mean 'bool'?");
+  static final StaticWarningCode UNDEFINED_CLASS_BOOLEAN = new StaticWarningCode('UNDEFINED_CLASS_BOOLEAN', 64, "Undefined class 'boolean'; did you mean 'bool'?");
 
   /**
    * 12.17 Getter Invocation: It is a static warning if there is no class <i>C</i> in the enclosing
@@ -2207,7 +2218,7 @@
    * @param getterName the name of the getter
    * @param enclosingType the name of the enclosing type where the getter is being looked for
    */
-  static final StaticWarningCode UNDEFINED_GETTER = new StaticWarningCode('UNDEFINED_GETTER', 62, "There is no such getter '%s' in '%s'");
+  static final StaticWarningCode UNDEFINED_GETTER = new StaticWarningCode('UNDEFINED_GETTER', 65, "There is no such getter '%s' in '%s'");
 
   /**
    * 12.30 Identifier Reference: It is as static warning if an identifier expression of the form
@@ -2215,7 +2226,7 @@
    * setter) or variable initializer and there is no declaration <i>d</i> with name <i>id</i> in the
    * lexical scope enclosing the expression.
    */
-  static final StaticWarningCode UNDEFINED_IDENTIFIER = new StaticWarningCode('UNDEFINED_IDENTIFIER', 63, "Undefined name '%s'");
+  static final StaticWarningCode UNDEFINED_IDENTIFIER = new StaticWarningCode('UNDEFINED_IDENTIFIER', 66, "Undefined name '%s'");
 
   /**
    * 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub></i>, <i>1<=i<=l</i>,
@@ -2223,21 +2234,21 @@
    * <i>p<sub>n+k</sub></i>} or a static warning occurs.
    * @param name the name of the requested named parameter
    */
-  static final StaticWarningCode UNDEFINED_NAMED_PARAMETER = new StaticWarningCode('UNDEFINED_NAMED_PARAMETER', 64, "The named parameter '%s' is not defined");
+  static final StaticWarningCode UNDEFINED_NAMED_PARAMETER = new StaticWarningCode('UNDEFINED_NAMED_PARAMETER', 67, "The named parameter '%s' is not defined");
 
   /**
    * 12.18 Assignment: It is as static warning if an assignment of the form <i>v = e</i> occurs
    * inside a top level or static function (be it function, method, getter, or setter) or variable
    * initializer and there is no declaration <i>d</i> with name <i>v=</i> in the lexical scope
    * enclosing the assignment.
-   * <p>
+   *
    * 12.18 Assignment: It is a static warning if there is no class <i>C</i> in the enclosing lexical
    * scope of the assignment, or if <i>C</i> does not declare, implicitly or explicitly, a setter
    * <i>v=</i>.
    * @param setterName the name of the getter
    * @param enclosingType the name of the enclosing type where the setter is being looked for
    */
-  static final StaticWarningCode UNDEFINED_SETTER = new StaticWarningCode('UNDEFINED_SETTER', 65, "There is no such setter '%s' in '%s'");
+  static final StaticWarningCode UNDEFINED_SETTER = new StaticWarningCode('UNDEFINED_SETTER', 68, "There is no such setter '%s' in '%s'");
 
   /**
    * 12.15.3 Static Invocation: It is a static warning if <i>C</i> does not declare a static method
@@ -2245,8 +2256,8 @@
    * @param methodName the name of the method
    * @param enclosingType the name of the enclosing type where the method is being looked for
    */
-  static final StaticWarningCode UNDEFINED_STATIC_METHOD_OR_GETTER = new StaticWarningCode('UNDEFINED_STATIC_METHOD_OR_GETTER', 66, "There is no such static method '%s' in '%s'");
-  static final List<StaticWarningCode> values = [AMBIGUOUS_IMPORT, ARGUMENT_TYPE_NOT_ASSIGNABLE, ASSIGNMENT_TO_FINAL, CASE_BLOCK_NOT_TERMINATED, CAST_TO_NON_TYPE, COMMENT_REFERENCE_CONSTRUCTOR_NOT_VISIBLE, COMMENT_REFERENCE_IDENTIFIER_NOT_VISIBLE, COMMENT_REFERENCE_UNDECLARED_CONSTRUCTOR, COMMENT_REFERENCE_UNDECLARED_IDENTIFIER, COMMENT_REFERENCE_URI_NOT_LIBRARY, CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER, CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER, CONST_WITH_ABSTRACT_CLASS, EQUAL_KEYS_IN_MAP, EXPORT_DUPLICATED_LIBRARY_NAME, EXTRA_POSITIONAL_ARGUMENTS, FIELD_INITIALIZER_NOT_ASSIGNABLE, FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, FINAL_NOT_INITIALIZED, IMPORT_DUPLICATED_LIBRARY_NAME, INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, INCORRECT_NUMBER_OF_ARGUMENTS, INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, INVALID_FACTORY_NAME, INVALID_GETTER_OVERRIDE_RETURN_TYPE, INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE, INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE, INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE, INVALID_METHOD_OVERRIDE_RETURN_TYPE, INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES, INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE, INVOCATION_OF_NON_FUNCTION, MISMATCHED_GETTER_AND_SETTER_TYPES, NEW_WITH_ABSTRACT_CLASS, NEW_WITH_NON_TYPE, NEW_WITH_UNDEFINED_CONSTRUCTOR, NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, NON_TYPE_IN_CATCH_CLAUSE, NON_VOID_RETURN_FOR_OPERATOR, NON_VOID_RETURN_FOR_SETTER, NOT_A_TYPE, NOT_ENOUGH_REQUIRED_ARGUMENTS, PART_OF_DIFFERENT_LIBRARY, REDIRECT_TO_INVALID_FUNCTION_TYPE, REDIRECT_TO_INVALID_RETURN_TYPE, REDIRECT_TO_MISSING_CONSTRUCTOR, REDIRECT_TO_NON_CLASS, RETURN_WITHOUT_VALUE, STATIC_ACCESS_TO_INSTANCE_MEMBER, SWITCH_EXPRESSION_NOT_ASSIGNABLE, TYPE_TEST_NON_TYPE, TYPE_VARIABLE_IN_STATIC_SCOPE, UNDEFINED_CLASS, UNDEFINED_CLASS_BOOLEAN, UNDEFINED_GETTER, UNDEFINED_IDENTIFIER, UNDEFINED_NAMED_PARAMETER, UNDEFINED_SETTER, UNDEFINED_STATIC_METHOD_OR_GETTER];
+  static final StaticWarningCode UNDEFINED_STATIC_METHOD_OR_GETTER = new StaticWarningCode('UNDEFINED_STATIC_METHOD_OR_GETTER', 69, "There is no such static method '%s' in '%s'");
+  static final List<StaticWarningCode> values = [AMBIGUOUS_IMPORT, ARGUMENT_TYPE_NOT_ASSIGNABLE, ASSIGNMENT_TO_FINAL, CASE_BLOCK_NOT_TERMINATED, CAST_TO_NON_TYPE, COMMENT_REFERENCE_CONSTRUCTOR_NOT_VISIBLE, COMMENT_REFERENCE_IDENTIFIER_NOT_VISIBLE, COMMENT_REFERENCE_UNDECLARED_CONSTRUCTOR, COMMENT_REFERENCE_UNDECLARED_IDENTIFIER, COMMENT_REFERENCE_URI_NOT_LIBRARY, CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER, CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER, CONST_WITH_ABSTRACT_CLASS, EQUAL_KEYS_IN_MAP, EXPORT_DUPLICATED_LIBRARY_NAME, EXTRA_POSITIONAL_ARGUMENTS, FIELD_INITIALIZER_NOT_ASSIGNABLE, FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, FINAL_NOT_INITIALIZED, IMPORT_DUPLICATED_LIBRARY_NAME, INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, INCORRECT_NUMBER_OF_ARGUMENTS, INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, INVALID_FACTORY_NAME, INVALID_GETTER_OVERRIDE_RETURN_TYPE, INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE, INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE, INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE, INVALID_METHOD_OVERRIDE_RETURN_TYPE, INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED, INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL, INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE, INVOCATION_OF_NON_FUNCTION, MISMATCHED_GETTER_AND_SETTER_TYPES, NEW_WITH_ABSTRACT_CLASS, NEW_WITH_NON_TYPE, NEW_WITH_UNDEFINED_CONSTRUCTOR, NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, NON_TYPE_IN_CATCH_CLAUSE, NON_VOID_RETURN_FOR_OPERATOR, NON_VOID_RETURN_FOR_SETTER, NOT_A_TYPE, NOT_ENOUGH_REQUIRED_ARGUMENTS, PART_OF_DIFFERENT_LIBRARY, REDIRECT_TO_INVALID_FUNCTION_TYPE, REDIRECT_TO_INVALID_RETURN_TYPE, REDIRECT_TO_MISSING_CONSTRUCTOR, REDIRECT_TO_NON_CLASS, RETURN_WITHOUT_VALUE, STATIC_ACCESS_TO_INSTANCE_MEMBER, SWITCH_EXPRESSION_NOT_ASSIGNABLE, TYPE_TEST_NON_TYPE, TYPE_VARIABLE_IN_STATIC_SCOPE, UNDEFINED_CLASS, UNDEFINED_CLASS_BOOLEAN, UNDEFINED_GETTER, UNDEFINED_IDENTIFIER, UNDEFINED_NAMED_PARAMETER, UNDEFINED_SETTER, UNDEFINED_STATIC_METHOD_OR_GETTER];
 
   /// The name of this enum constant, as declared in the enum declaration.
   final String name;
@@ -2274,7 +2285,7 @@
   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.
+ * The interface `AnalysisErrorListener` defines the behavior of objects that listen for[AnalysisError analysis errors] being produced by the analysis engine.
  * @coverage dart.engine.error
  */
 abstract class AnalysisErrorListener {
@@ -2286,7 +2297,7 @@
 
   /**
    * 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})
+   * @param error the error that was just found (not `null`)
    */
   void onError(AnalysisError error);
 }
@@ -2295,7 +2306,7 @@
   }
 }
 /**
- * The enumeration {@code HtmlWarningCode} defines the error codes used for warnings in HTML files.
+ * The enumeration `HtmlWarningCode` defines the error codes used for warnings in HTML files.
  * 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.
@@ -2344,7 +2355,7 @@
   String toString() => name;
 }
 /**
- * The enumeration {@code StaticTypeWarningCode} defines the error codes used for static type
+ * The enumeration `StaticTypeWarningCode` defines the error codes used for static type
  * warnings. 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.
@@ -2364,19 +2375,19 @@
    * &hellip; m<sub>k</sub></i> with the same name <i>n</i> that would be inherited (because
    * identically named members existed in several superinterfaces) then at most one member is
    * inherited.
-   * <p>
+   *
    * If the static types <i>T<sub>1</sub>, &hellip;, T<sub>k</sub></i> of the members
    * <i>m<sub>1</sub>, &hellip;, m<sub>k</sub></i> are not identical, then there must be a member
    * <i>m<sub>x</sub></i> such that <i>T<sub>x</sub> &lt; T<sub>i</sub>, 1 &lt;= x &lt;= k</i> for
    * all <i>i, 1 &lt;= i &lt; k</i>, or a static type warning occurs. The member that is inherited
    * is <i>m<sub>x</sub></i>, if it exists; otherwise:
    * <ol>
-   * <li>If all of <i>m<sub>1</sub>, &hellip; m<sub>k</sub></i> have the same number <i>r</i> of
+   * * If all of <i>m<sub>1</sub>, &hellip; m<sub>k</sub></i> have the same number <i>r</i> of
    * required parameters and the same set of named parameters <i>s</i>, then let <i>h = max(
    * numberOfOptionalPositionals( m<sub>i</sub> ) ), 1 &lt;= i &lt;= k</i>. <i>I</i> has a method
    * named <i>n</i>, with <i>r</i> required parameters of type dynamic, <i>h</i> optional positional
    * parameters of type dynamic, named parameters <i>s</i> of type dynamic and return type dynamic.
-   * <li>Otherwise none of the members <i>m<sub>1</sub>, &hellip;, m<sub>k</sub></i> is inherited.
+   * * Otherwise none of the members <i>m<sub>1</sub>, &hellip;, m<sub>k</sub></i> is inherited.
    * </ol>
    */
   static final StaticTypeWarningCode INCONSISTENT_METHOD_INHERITANCE = new StaticTypeWarningCode('INCONSISTENT_METHOD_INHERITANCE', 1, "'%s' is inherited by at least two interfaces inconsistently");
@@ -2385,11 +2396,11 @@
    * 12.18 Assignment: It is a static type warning if the static type of <i>e</i> may not be
    * assigned to the static type of <i>v</i>. The static type of the expression <i>v = e</i> is the
    * static type of <i>e</i>.
-   * <p>
+   *
    * 12.18 Assignment: It is a static type warning if the static type of <i>e</i> may not be
    * assigned to the static type of <i>C.v</i>. The static type of the expression <i>C.v = e</i> is
    * the static type of <i>e</i>.
-   * <p>
+   *
    * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static type
    * warning if the static type of <i>e<sub>2</sub></i> may not be assigned to <i>T</i>.
    * @param rhsTypeName the name of the right hand side type
@@ -2401,19 +2412,19 @@
    * 12.14.4 Function Expression Invocation: A function expression invocation <i>i</i> has the form
    * <i>e<sub>f</sub>(a<sub>1</sub>, &hellip; a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
    * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i>e<sub>f</sub></i> is an expression.
-   * <p>
+   *
    * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub></i> may not be
    * assigned to a function type.
-   * <p>
+   *
    * 12.15.1 Ordinary Invocation: An ordinary method invocation <i>i</i> has the form
    * <i>o.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip;
    * x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
-   * <p>
+   *
    * Let <i>T</i> be the static type of <i>o</i>. It is a static type warning if <i>T</i> does not
    * have an accessible instance member named <i>m</i>. If <i>T.m</i> exists, it is a static warning
    * if the type <i>F</i> of <i>T.m</i> may not be assigned to a function type. If <i>T.m</i> does
    * not exist, or if <i>F</i> is not a function type, the static type of <i>i</i> is dynamic.
-   * <p>
+   *
    * 12.15.3 Static Invocation: It is a static type warning if the type <i>F</i> of <i>C.m</i> may
    * not be assigned to a function type.
    * @param nonFunctionIdentifier the name of the identifier that is not a function type
@@ -2423,12 +2434,12 @@
   /**
    * 12.19 Conditional: It is a static type warning if the type of <i>e<sub>1</sub></i> may not be
    * assigned to bool.
-   * <p>
+   *
    * 13.5 If: It is a static type warning if the type of the expression <i>b</i> may not be assigned
    * to bool.
-   * <p>
+   *
    * 13.7 While: It is a static type warning if the type of <i>e</i> may not be assigned to bool.
-   * <p>
+   *
    * 13.8 Do: It is a static type warning if the type of <i>e</i> cannot be assigned to bool.
    */
   static final StaticTypeWarningCode NON_BOOL_CONDITION = new StaticTypeWarningCode('NON_BOOL_CONDITION', 4, "Conditions must have a static type of 'bool'");
@@ -2473,7 +2484,7 @@
 
   /**
    * 10 Generics: It is a static type warning if a type parameter is a supertype of its upper bound.
-   * <p>
+   *
    * 15.8 Parameterized Types: If <i>S</i> is the static type of a member <i>m</i> of <i>G</i>, then
    * the static type of the member <i>m</i> of <i>G&lt;A<sub>1</sub>, &hellip; A<sub>n</sub>&gt;</i>
    * is <i>\[A<sub>1</sub>, &hellip;, A<sub>n</sub>/T<sub>1</sub>, &hellip;, T<sub>n</sub>\]S</i>
@@ -2485,7 +2496,7 @@
   static final StaticTypeWarningCode TYPE_ARGUMENT_VIOLATES_BOUNDS = new StaticTypeWarningCode('TYPE_ARGUMENT_VIOLATES_BOUNDS', 10, "");
 
   /**
-   * Specification reference needed. This is equivalent to {@link #UNDEFINED_METHOD}, but for
+   * Specification reference needed. This is equivalent to [UNDEFINED_METHOD], but for
    * top-level functions.
    * @param methodName the name of the method that is undefined
    */
@@ -2512,11 +2523,11 @@
    * <i>e<sub>1</sub></i>\[<i>e<sub>2</sub></i>\] = <i>e<sub>3</sub></i> is equivalent to the
    * evaluation of the expression (a, i, e){a.\[\]=(i, e); return e;} (<i>e<sub>1</sub></i>,
    * <i>e<sub>2</sub></i>, <i>e<sub>2</sub></i>).
-   * <p>
+   *
    * 12.29 Assignable Expressions: An assignable expression of the form
    * <i>e<sub>1</sub></i>\[<i>e<sub>2</sub></i>\] is evaluated as a method invocation of the operator
    * method \[\] on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.
-   * <p>
+   *
    * 12.15.1 Ordinary Invocation: Let <i>T</i> be the static type of <i>o</i>. It is a static type
    * warning if <i>T</i> does not have an accessible instance member named <i>m</i>.
    * @param operator the name of the operator
diff --git a/pkg/analyzer_experimental/lib/src/generated/html.dart b/pkg/analyzer_experimental/lib/src/generated/html.dart
index 02ca349..c667f7b 100644
--- a/pkg/analyzer_experimental/lib/src/generated/html.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/html.dart
@@ -10,7 +10,7 @@
 import 'element.dart' show HtmlElementImpl;
 import 'engine.dart' show AnalysisEngine;
 /**
- * Instances of the class {@code Token} represent a token that was scanned from the input. Each
+ * Instances of the class `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.
  * @coverage dart.engine.html
  */
@@ -43,7 +43,7 @@
 
   /**
    * Initialize a newly created token.
-   * @param type the token type (not {@code null})
+   * @param type the token type (not `null`)
    * @param offset the offset from the beginning of the file to the first character in the token
    */
   Token.con1(TokenType type, int offset) {
@@ -55,9 +55,9 @@
 
   /**
    * Initialize a newly created token.
-   * @param type the token type (not {@code null})
+   * @param type the token type (not `null`)
    * @param offset the offset from the beginning of the file to the first character in the token
-   * @param value the lexeme represented by this token (not {@code null})
+   * @param value the lexeme represented by this token (not `null`)
    */
   Token.con2(TokenType type2, int offset2, String value2) {
     _jtd_constructor_156_impl(type2, offset2, value2);
@@ -84,7 +84,7 @@
 
   /**
    * Return the lexeme that represents this token.
-   * @return the lexeme (not {@code null})
+   * @return the lexeme (not `null`)
    */
   String get lexeme => _value;
 
@@ -108,17 +108,17 @@
 
   /**
    * Answer the token type for the receiver.
-   * @return the token type (not {@code null})
+   * @return the token type (not `null`)
    */
   TokenType get type => _type;
 
   /**
-   * Return {@code true} if this token is a synthetic token. A synthetic token is a token that was
+   * Return `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
+   * have a length of zero (`0`).
+   * @return `true` if this token is a synthetic token
    */
-  bool isSynthetic() => length == 0;
+  bool get isSynthetic => length == 0;
 
   /**
    * Set the next token in the token stream to the given token. This has the side-effect of setting
@@ -142,13 +142,13 @@
   }
 }
 /**
- * Instances of {@code HtmlParseResult} hold the result of parsing an HTML file.
+ * Instances of `HtmlParseResult` hold the result of parsing an HTML file.
  * @coverage dart.engine.html
  */
 class HtmlParseResult extends HtmlScanResult {
 
   /**
-   * The unit containing the parsed information (not {@code null}).
+   * The unit containing the parsed information (not `null`).
    */
   HtmlUnit _unit;
   HtmlParseResult(int modificationTime, Token token, List<int> lineStarts, HtmlUnit unit) : super(modificationTime, token, lineStarts) {
@@ -157,15 +157,15 @@
 
   /**
    * Answer the unit generated by parsing the source
-   * @return the unit (not {@code null})
+   * @return the unit (not `null`)
    */
   HtmlUnit get htmlUnit => _unit;
 }
 /**
- * Instances of the class {@code RecursiveXmlVisitor} implement an XML visitor that will recursively
+ * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that will recursively
  * visit all of the nodes in an XML structure. For example, using an instance of this class to visit
- * a {@link XmlTagNode} will also cause all of the contained {@link XmlAttributeNode}s and{@link XmlTagNode}s to be visited.
- * <p>
+ * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and[XmlTagNode]s to be visited.
+ *
  * 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.
@@ -186,13 +186,13 @@
   }
 }
 /**
- * The abstract class {@code XmlNode} defines behavior common to all XML/HTML nodes.
+ * The abstract class `XmlNode` defines behavior common to all XML/HTML nodes.
  * @coverage dart.engine.html
  */
 abstract class XmlNode {
 
   /**
-   * The parent of the node, or {@code null} if the node is the root of an AST structure.
+   * The parent of the node, or `null` if the node is the root of an AST structure.
    */
   XmlNode _parent;
 
@@ -205,13 +205,13 @@
 
   /**
    * Return the first token included in this node's source range.
-   * @return the first token or {@code null} if none
+   * @return the first token or `null` if none
    */
   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 an html
+   * source range. This is equivalent to `node.getOffset() + node.getLength()`. For an html
    * unit this will be equal to the length of the unit's source.
    * @return the offset of the character just past the node's source range
    */
@@ -219,7 +219,7 @@
 
   /**
    * Return the last token included in this node's source range.
-   * @return the last token or {@code null} if none
+   * @return the last token or `null` if none
    */
   Token get endToken;
 
@@ -251,11 +251,11 @@
   }
 
   /**
-   * Return this node's parent node, or {@code null} if this node is the root of an AST structure.
-   * <p>
+   * Return this node's parent node, or `null` if this node is the root of an AST structure.
+   *
    * 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
+   * @return the parent of this node, or `null` if none
    */
   XmlNode get parent => _parent;
   String toString() {
@@ -353,7 +353,7 @@
   }
 }
 /**
- * Instances of the class {@code SimpleXmlVisitor} implement an AST visitor that will do nothing
+ * Instances of the class `SimpleXmlVisitor` 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.
@@ -364,7 +364,7 @@
   R visitXmlTagNode(XmlTagNode xmlTagNode) => null;
 }
 /**
- * The abstract class {@code AbstractScanner} implements a scanner for HTML code. Subclasses are
+ * The abstract class `AbstractScanner` implements a scanner for HTML code. Subclasses are
  * required to implement the interface used to access the characters being scanned.
  * @coverage dart.engine.html
  */
@@ -424,7 +424,7 @@
 
   /**
    * Answer the source being scanned.
-   * @return the source or {@code null} if undefined
+   * @return the source or `null` if undefined
    */
   Source get source => _source;
 
@@ -638,7 +638,7 @@
   }
 }
 /**
- * Instances of {@code HtmlScanResult} hold the result of scanning an HTML file.
+ * Instances of `HtmlScanResult` hold the result of scanning an HTML file.
  * @coverage dart.engine.html
  */
 class HtmlScanResult {
@@ -649,7 +649,7 @@
   int _modificationTime = 0;
 
   /**
-   * The first token in the token stream (not {@code null}).
+   * The first token in the token stream (not `null`).
    */
   Token _token;
 
@@ -665,7 +665,7 @@
 
   /**
    * Answer the line start information that was produced.
-   * @return an array of line starts (not {@code null})
+   * @return an array of line starts (not `null`)
    */
   List<int> get lineStarts => _lineStarts;
 
@@ -677,12 +677,12 @@
 
   /**
    * Answer the first token in the token stream.
-   * @return the token (not {@code null})
+   * @return the token (not `null`)
    */
   Token get token => _token;
 }
 /**
- * Instances of the class {@code StringScanner} implement a scanner that reads from a string. The
+ * Instances of the class `StringScanner` implement a scanner that reads from a string. The
  * scanning logic is in the superclass.
  * @coverage dart.engine.html
  */
@@ -733,7 +733,7 @@
   }
 }
 /**
- * Instances of the class {@code CharBufferScanner} implement a scanner that reads from a character
+ * Instances of the class `CharBufferScanner` implement a scanner that reads from a character
  * buffer. The scanning logic is in the superclass.
  * @coverage dart.engine.html
  */
@@ -781,7 +781,7 @@
   }
 }
 /**
- * Instances of the class {@code ToSourceVisitor} write a source representation of a visited XML
+ * Instances of the class `ToSourceVisitor` write a source representation of a visited XML
  * node (and all of it's children) to a writer.
  * @coverage dart.engine.html
  */
@@ -853,7 +853,7 @@
   }
 }
 /**
- * The enumeration {@code TokenType} defines the types of tokens that can be returned by the
+ * The enumeration `TokenType` defines the types of tokens that can be returned by the
  * scanner.
  * @coverage dart.engine.html
  */
@@ -883,7 +883,7 @@
   final int ordinal;
 
   /**
-   * The lexeme that defines this type of token, or {@code null} if there is more than one possible
+   * The lexeme that defines this type of token, or `null` if there is more than one possible
    * lexeme for this type of token.
    */
   String _lexeme;
@@ -892,7 +892,7 @@
   }
 
   /**
-   * Return the lexeme that defines this type of token, or {@code null} if there is more than one
+   * Return the lexeme that defines this type of token, or `null` if there is more than one
    * possible lexeme for this type of token.
    * @return the lexeme that defines this type of token
    */
@@ -906,7 +906,7 @@
   String toString() => "-eof-";
 }
 /**
- * Instances of {@code XmlAttributeNode} represent name/value pairs owned by an {@link XmlTagNode}.
+ * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTagNode].
  * @coverage dart.engine.html
  */
 class XmlAttributeNode extends XmlNode {
@@ -916,10 +916,10 @@
 
   /**
    * Construct a new instance representing an XML attribute.
-   * @param name the name token (not {@code null}). This may be a zero length token if the attribute
+   * @param name the name token (not `null`). This may be a zero length token if the attribute
    * is badly formed.
-   * @param equals the equals sign or {@code null} if none
-   * @param value the value token (not {@code null})
+   * @param equals the equals sign or `null` if none
+   * @param value the value token (not `null`)
    */
   XmlAttributeNode(Token name, Token equals, Token value) {
     this._name = name;
@@ -931,20 +931,20 @@
   Token get endToken => _value;
 
   /**
-   * Answer the equals sign token that appears between the name and value tokens. This may be{@code null} if the attribute is badly formed.
-   * @return the token or {@code null} if there is no equals sign between the name and value
+   * Answer the equals sign token that appears between the name and value tokens. This may be`null` if the attribute is badly formed.
+   * @return the token or `null` if there is no equals sign between the name and value
    */
   Token get equals => _equals;
 
   /**
    * Answer the attribute name. This may be a zero length token if the attribute is badly formed.
-   * @return the name (not {@code null})
+   * @return the name (not `null`)
    */
   Token get name => _name;
 
   /**
    * Answer the lexeme for the value token without the leading and trailing quotes.
-   * @return the text or {@code null} if the value is not specified
+   * @return the text or `null` if the value is not specified
    */
   String get text {
     if (_value == null) {
@@ -973,14 +973,14 @@
   /**
    * Answer the attribute value. A properly formed value will start and end with matching quote
    * characters, but the value returned may not be properly formed.
-   * @return the value or {@code null} if this represents a badly formed attribute
+   * @return the value or `null` if this represents a badly formed attribute
    */
   Token get value => _value;
   void visitChildren(XmlVisitor<Object> visitor) {
   }
 }
 /**
- * The interface {@code XmlVisitor} defines the behavior of objects that can be used to visit an{@link XmlNode} structure.
+ * The interface `XmlVisitor` defines the behavior of objects that can be used to visit an[XmlNode] structure.
  * @coverage dart.engine.html
  */
 abstract class XmlVisitor<R> {
@@ -989,7 +989,7 @@
   R visitXmlTagNode(XmlTagNode xmlTagNode);
 }
 /**
- * Instances of {@code HtmlScanner} receive and scan HTML content from a {@link Source}.<br/>
+ * Instances of `HtmlScanner` receive and scan HTML content from a [Source].<br/>
  * For example, the following code scans HTML source and returns the result:
  * <pre>
  * HtmlScanner scanner = new HtmlScanner(source);
@@ -1002,7 +1002,7 @@
   List<String> _SCRIPT_TAG = <String> ["script"];
 
   /**
-   * The source being scanned (not {@code null})
+   * The source being scanned (not `null`)
    */
   Source _source;
 
@@ -1023,7 +1023,7 @@
 
   /**
    * Construct a new instance to scan the specified source.
-   * @param source the source to be scanned (not {@code null})
+   * @param source the source to be scanned (not `null`)
    */
   HtmlScanner(Source source) {
     this._source = source;
@@ -1043,13 +1043,13 @@
 
   /**
    * Answer the result of scanning the source
-   * @return the result (not {@code null})
+   * @return the result (not `null`)
    */
   HtmlScanResult get result => new HtmlScanResult(_modificationTime, _token, _scanner.lineStarts);
 }
 /**
- * Instances of the class {@code XmlParser} are used to parse tokens into a AST structure comprised
- * of {@link XmlNode}s.
+ * Instances of the class `XmlParser` are used to parse tokens into a AST structure comprised
+ * of [XmlNode]s.
  * @coverage dart.engine.html
  */
 class XmlParser {
@@ -1079,17 +1079,17 @@
   Source get source => _source;
 
   /**
-   * Answer {@code true} if the specified tag is self closing and thus should never have content or
+   * Answer `true` if the specified tag is self closing and thus should never have content or
    * child tag nodes.
-   * @param tag the tag (not {@code null})
-   * @return {@code true} if self closing
+   * @param tag the tag (not `null`)
+   * @return `true` if self closing
    */
   bool isSelfClosing(Token tag) => false;
 
   /**
    * Parse the entire token stream and in the process, advance the current token to the end of the
    * token stream.
-   * @return the list of tag nodes found (not {@code null}, contains no {@code null})
+   * @return the list of tag nodes found (not `null`, contains no `null`)
    */
   List<XmlTagNode> parseTopTagNodes(Token firstToken) {
     _currentToken = firstToken;
@@ -1119,8 +1119,8 @@
 
   /**
    * Insert a synthetic token of the specified type before the current token
-   * @param type the type of token to be inserted (not {@code null})
-   * @return the synthetic token that was inserted (not {@code null})
+   * @param type the type of token to be inserted (not `null`)
+   * @return the synthetic token that was inserted (not `null`)
    */
   Token insertSyntheticToken(TokenType type) {
     Token token = new Token.con2(type, _currentToken.offset, "");
@@ -1131,8 +1131,8 @@
 
   /**
    * Parse the token stream for an attribute. This method advances the current token over the
-   * attribute, but should not be called if the {@link #currentToken} is not {@link TokenType#TAG}.
-   * @return the attribute (not {@code null})
+   * attribute, but should not be called if the [currentToken] is not [TokenType#TAG].
+   * @return the attribute (not `null`)
    */
   XmlAttributeNode parseAttribute() {
     Token name = _currentToken;
@@ -1158,8 +1158,8 @@
 
   /**
    * Parse the stream for a sequence of attributes. This method advances the current token to the
-   * next {@link TokenType#GT}, {@link TokenType#SLASH_GT}, or {@link TokenType#EOF}.
-   * @return a collection of zero or more attributes (not {@code null}, contains no {@code null}s)
+   * next [TokenType#GT], [TokenType#SLASH_GT], or [TokenType#EOF].
+   * @return a collection of zero or more attributes (not `null`, contains no `null`s)
    */
   List<XmlAttributeNode> parseAttributes() {
     TokenType type = _currentToken.type;
@@ -1184,8 +1184,8 @@
 
   /**
    * Parse the stream for a sequence of tag nodes existing within a parent tag node. This method
-   * advances the current token to the next {@link TokenType#LT_SLASH} or {@link TokenType#EOF}.
-   * @return a list of nodes (not {@code null}, contains no {@code null}s)
+   * advances the current token to the next [TokenType#LT_SLASH] or [TokenType#EOF].
+   * @return a list of nodes (not `null`, contains no `null`s)
    */
   List<XmlTagNode> parseChildTagNodes() {
     TokenType type = _currentToken.type;
@@ -1212,8 +1212,8 @@
 
   /**
    * Parse the token stream for the next tag node. This method advances current token over the
-   * parsed tag node, but should only be called if the current token is {@link TokenType#LT}
-   * @return the tag node or {@code null} if none found
+   * parsed tag node, but should only be called if the current token is [TokenType#LT]
+   * @return the tag node or `null` if none found
    */
   XmlTagNode parseTagNode() {
     Token nodeStart = _currentToken;
@@ -1273,7 +1273,7 @@
   }
 }
 /**
- * Instances of {@code XmlTagNode} represent XML or HTML elements such as {@code <p>} and{@code <body foo="bar"> ... </body>}.
+ * Instances of `XmlTagNode` represent XML or HTML elements such as `` and`<body foo="bar"> ... </body>`.
  * @coverage dart.engine.html
  */
 class XmlTagNode extends XmlNode {
@@ -1289,75 +1289,75 @@
   static List<XmlTagNode> NO_TAG_NODES = new UnmodifiableListView(new List<XmlTagNode>());
 
   /**
-   * The starting {@link TokenType#LT} token (not {@code null}).
+   * The starting [TokenType#LT] token (not `null`).
    */
   Token _nodeStart;
 
   /**
-   * The {@link TokenType#TAG} token after the starting '&lt;' (not {@code null}).
+   * The [TokenType#TAG] token after the starting '&lt;' (not `null`).
    */
   Token _tag;
 
   /**
-   * The attributes contained by the receiver (not {@code null}, contains no {@code null}s).
+   * The attributes contained by the receiver (not `null`, contains no `null`s).
    */
   List<XmlAttributeNode> _attributes;
 
   /**
-   * The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the attributes (not{@code null}). The token may be the same token as {@link #nodeEnd} if there are no child{@link #tagNodes}.
+   * The [TokenType#GT] or [TokenType#SLASH_GT] token after the attributes (not`null`). The token may be the same token as [nodeEnd] if there are no child[tagNodes].
    */
   Token _attributeEnd;
 
   /**
-   * The tag nodes contained in the receiver (not {@code null}, contains no {@code null}s).
+   * The tag nodes contained in the receiver (not `null`, contains no `null`s).
    */
   List<XmlTagNode> _tagNodes;
 
   /**
-   * The token (not {@code null}) after the content, which may be
-   * <ul>
-   * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</li>
-   * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is self
-   * closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
-   * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and is the last node in
-   * the stream {@link TokenType#LT_SLASH} token after the content, or {@code null} if there is no
-   * content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
-   * </ul>
+   * The token (not `null`) after the content, which may be
+   *
+   * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or
+   * * (2) the [TokenType#LT] nodeStart of the next sibling node if this node is self
+   * closing or the attributeEnd is [TokenType#SLASH_GT], or
+   * * (3) [TokenType#EOF] if the node does not have a closing tag and is the last node in
+   * the stream [TokenType#LT_SLASH] token after the content, or `null` if there is no
+   * content and the attributes ended with [TokenType#SLASH_GT].
+   *
    */
   Token _contentEnd;
 
   /**
-   * The closing {@link TokenType#TAG} after the child elements or {@code null} if there is no
-   * content and the attributes ended with {@link TokenType#SLASH_GT}
+   * The closing [TokenType#TAG] after the child elements or `null` if there is no
+   * content and the attributes ended with [TokenType#SLASH_GT]
    */
   Token _closingTag;
 
   /**
-   * The ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token (not {@code null}).
+   * The ending [TokenType#GT] or [TokenType#SLASH_GT] token (not `null`).
    */
   Token _nodeEnd;
 
   /**
    * Construct a new instance representing an XML or HTML element
-   * @param nodeStart the starting {@link TokenType#LT} token (not {@code null})
-   * @param tag the {@link TokenType#TAG} token after the starting '&lt;' (not {@code null}).
-   * @param attributes the attributes associated with this element or {@link #NO_ATTRIBUTES} (not{@code null}, contains no {@code null}s)
-   * @param attributeEnd The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the
-   * attributes (not {@code null}). The token may be the same token as {@link #nodeEnd} if
-   * there are no child {@link #tagNodes}.
-   * @param tagNodes child tag nodes of the receiver or {@link #NO_TAG_NODES} (not {@code null},
-   * contains no {@code null}s)
-   * @param contentEnd the token (not {@code null}) after the content, which may be
-   * <ul>
-   * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</li>
-   * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is
-   * self closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
-   * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and is the last
-   * node in the stream {@link TokenType#LT_SLASH} token after the content, or {@code null}if there is no content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
-   * </ul>
-   * @param closingTag the closing {@link TokenType#TAG} after the child elements or {@code null} if
-   * there is no content and the attributes ended with {@link TokenType#SLASH_GT}
-   * @param nodeEnd the ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token (not{@code null})
+   * @param nodeStart the starting [TokenType#LT] token (not `null`)
+   * @param tag the [TokenType#TAG] token after the starting '&lt;' (not `null`).
+   * @param attributes the attributes associated with this element or [NO_ATTRIBUTES] (not`null`, contains no `null`s)
+   * @param attributeEnd The [TokenType#GT] or [TokenType#SLASH_GT] token after the
+   * attributes (not `null`). The token may be the same token as [nodeEnd] if
+   * there are no child [tagNodes].
+   * @param tagNodes child tag nodes of the receiver or [NO_TAG_NODES] (not `null`,
+   * contains no `null`s)
+   * @param contentEnd the token (not `null`) after the content, which may be
+   *
+   * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or
+   * * (2) the [TokenType#LT] nodeStart of the next sibling node if this node is
+   * self closing or the attributeEnd is [TokenType#SLASH_GT], or
+   * * (3) [TokenType#EOF] if the node does not have a closing tag and is the last
+   * node in the stream [TokenType#LT_SLASH] token after the content, or `null`if there is no content and the attributes ended with [TokenType#SLASH_GT].
+   *
+   * @param closingTag the closing [TokenType#TAG] after the child elements or `null` if
+   * there is no content and the attributes ended with [TokenType#SLASH_GT]
+   * @param nodeEnd the ending [TokenType#GT] or [TokenType#SLASH_GT] token (not`null`)
    */
   XmlTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Token attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, Token nodeEnd) {
     this._nodeStart = nodeStart;
@@ -1374,7 +1374,7 @@
   /**
    * Answer the attribute with the specified name.
    * @param name the attribute name
-   * @return the attribute or {@code null} if no matching attribute is found
+   * @return the attribute or `null` if no matching attribute is found
    */
   XmlAttributeNode getAttribute(String name2) {
     for (XmlAttributeNode attribute in _attributes) {
@@ -1386,23 +1386,23 @@
   }
 
   /**
-   * The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the attributes (not{@code null}). The token may be the same token as {@link #nodeEnd} if there are no child{@link #tagNodes}.
-   * @return the token (not {@code null})
+   * The [TokenType#GT] or [TokenType#SLASH_GT] token after the attributes (not`null`). The token may be the same token as [nodeEnd] if there are no child[tagNodes].
+   * @return the token (not `null`)
    */
   Token get attributeEnd => _attributeEnd;
 
   /**
    * Answer the receiver's attributes. Callers should not manipulate the returned list to edit the
    * AST structure.
-   * @return the attributes (not {@code null}, contains no {@code null}s)
+   * @return the attributes (not `null`, contains no `null`s)
    */
   List<XmlAttributeNode> get attributes => _attributes;
 
   /**
-   * Find the attribute with the given name (see {@link #getAttribute(String)} and answer the lexeme
-   * for the attribute's value token without the leading and trailing quotes (see{@link XmlAttributeNode#getText()}).
+   * Find the attribute with the given name (see [getAttribute] and answer the lexeme
+   * for the attribute's value token without the leading and trailing quotes (see[XmlAttributeNode#getText]).
    * @param name the attribute name
-   * @return the attribute text or {@code null} if no matching attribute is found
+   * @return the attribute text or `null` if no matching attribute is found
    */
   String getAttributeText(String name) {
     XmlAttributeNode attribute = getAttribute(name);
@@ -1411,17 +1411,17 @@
   Token get beginToken => _nodeStart;
 
   /**
-   * The the closing {@link TokenType#TAG} after the child elements or {@code null} if there is no
-   * content and the attributes ended with {@link TokenType#SLASH_GT}
-   * @return the closing tag or {@code null}
+   * The the closing [TokenType#TAG] after the child elements or `null` if there is no
+   * content and the attributes ended with [TokenType#SLASH_GT]
+   * @return the closing tag or `null`
    */
   Token get closingTag => _closingTag;
 
   /**
    * Answer a string representing the content contained in the receiver. This includes the textual
-   * representation of any child tag nodes ({@link #getTagNodes()}). Whitespace between '&lt;',
+   * representation of any child tag nodes ([getTagNodes]). Whitespace between '&lt;',
    * '&lt;/', and '>', '/>' is discarded, but all other whitespace is preserved.
-   * @return the content (not {@code null})
+   * @return the content (not `null`)
    */
   String get content {
     Token token = _attributeEnd.next;
@@ -1442,16 +1442,16 @@
   }
 
   /**
-   * Answer the token (not {@code null}) after the content, which may be
-   * <ul>
-   * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</li>
-   * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is self
-   * closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
-   * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and is the last node in
-   * the stream {@link TokenType#LT_SLASH} token after the content, or {@code null} if there is no
-   * content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
-   * </ul>
-   * @return the token (not {@code null})
+   * Answer the token (not `null`) after the content, which may be
+   *
+   * * (1) [TokenType#LT_SLASH] for nodes with open and close tags, or
+   * * (2) the [TokenType#LT] nodeStart of the next sibling node if this node is self
+   * closing or the attributeEnd is [TokenType#SLASH_GT], or
+   * * (3) [TokenType#EOF] if the node does not have a closing tag and is the last node in
+   * the stream [TokenType#LT_SLASH] token after the content, or `null` if there is no
+   * content and the attributes ended with [TokenType#SLASH_GT].
+   *
+   * @return the token (not `null`)
    */
   Token get contentEnd => _contentEnd;
   Token get endToken {
@@ -1477,27 +1477,27 @@
   }
 
   /**
-   * Answer the ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token.
-   * @return the token (not {@code null})
+   * Answer the ending [TokenType#GT] or [TokenType#SLASH_GT] token.
+   * @return the token (not `null`)
    */
   Token get nodeEnd => _nodeEnd;
 
   /**
-   * Answer the starting {@link TokenType#LT} token.
-   * @return the token (not {@code null})
+   * Answer the starting [TokenType#LT] token.
+   * @return the token (not `null`)
    */
   Token get nodeStart => _nodeStart;
 
   /**
-   * Answer the {@link TokenType#TAG} token after the starting '&lt;'.
-   * @return the token (not {@code null})
+   * Answer the [TokenType#TAG] token after the starting '&lt;'.
+   * @return the token (not `null`)
    */
   Token get tag => _tag;
 
   /**
    * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
    * to edit the AST structure.
-   * @return the children (not {@code null}, contains no {@code null}s)
+   * @return the children (not `null`, contains no `null`s)
    */
   List<XmlTagNode> get tagNodes => _tagNodes;
   void visitChildren(XmlVisitor<Object> visitor) {
@@ -1510,7 +1510,7 @@
   }
 
   /**
-   * Same as {@link #becomeParentOf(List)}, but returns given "ifEmpty" if "children" is empty
+   * Same as [becomeParentOf], but returns given "ifEmpty" if "children" is empty
    */
   List becomeParentOfEmpty(List children, List ifEmpty) {
     if (children != null && children.isEmpty) {
@@ -1520,8 +1520,8 @@
   }
 }
 /**
- * Instances of the class {@code HtmlParser} are used to parse tokens into a AST structure comprised
- * of {@link XmlNode}s.
+ * Instances of the class `HtmlParser` are used to parse tokens into a AST structure comprised
+ * of [XmlNode]s.
  * @coverage dart.engine.html
  */
 class HtmlParser extends XmlParser {
@@ -1536,8 +1536,8 @@
 
   /**
    * Parse the tokens specified by the given scan result.
-   * @param scanResult the result of scanning an HTML source (not {@code null})
-   * @return the parse result (not {@code null})
+   * @param scanResult the result of scanning an HTML source (not `null`)
+   * @return the parse result (not `null`)
    */
   HtmlParseResult parse(HtmlScanResult scanResult) {
     Token firstToken = scanResult.token;
@@ -1548,8 +1548,8 @@
 
   /**
    * Scan then parse the specified source.
-   * @param source the source to be scanned and parsed (not {@code null})
-   * @return the parse result (not {@code null})
+   * @param source the source to be scanned and parsed (not `null`)
+   * @return the parse result (not `null`)
    */
   HtmlParseResult parse2(Source source) {
     HtmlScanner scanner = new HtmlScanner(source);
@@ -1559,7 +1559,7 @@
   bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme);
 }
 /**
- * Instances of the class {@code HtmlUnit} represent the contents of an HTML file.
+ * Instances of the class `HtmlUnit` represent the contents of an HTML file.
  * @coverage dart.engine.html
  */
 class HtmlUnit extends XmlNode {
@@ -1571,25 +1571,25 @@
 
   /**
    * 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}.
+   * should always have a type of [TokenType.EOF].
    */
   Token _endToken;
 
   /**
-   * The tag nodes contained in the receiver (not {@code null}, contains no {@code null}s).
+   * The tag nodes contained in the receiver (not `null`, contains no `null`s).
    */
   List<XmlTagNode> _tagNodes;
 
   /**
-   * The element associated with this HTML unit or {@code null} if the receiver is not resolved.
+   * The element associated with this HTML unit or `null` if the receiver is not resolved.
    */
   HtmlElementImpl _element;
 
   /**
    * Construct a new instance representing the content of an HTML file.
-   * @param beginToken the first token in the file (not {@code null})
-   * @param tagNodes child tag nodes of the receiver (not {@code null}, contains no {@code null}s)
-   * @param endToken the last token in the token stream which should be of type{@link TokenType.EOF}
+   * @param beginToken the first token in the file (not `null`)
+   * @param tagNodes child tag nodes of the receiver (not `null`, contains no `null`s)
+   * @param endToken the last token in the token stream which should be of type[TokenType.EOF]
    */
   HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) {
     this._beginToken = beginToken;
@@ -1601,7 +1601,7 @@
 
   /**
    * Return the element associated with this HTML unit.
-   * @return the element or {@code null} if the receiver is not resolved
+   * @return the element or `null` if the receiver is not resolved
    */
   HtmlElementImpl get element => _element;
   Token get endToken => _endToken;
@@ -1609,7 +1609,7 @@
   /**
    * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
    * to edit the AST structure.
-   * @return the children (not {@code null}, contains no {@code null}s)
+   * @return the children (not `null`, contains no `null`s)
    */
   List<XmlTagNode> get tagNodes => _tagNodes;
 
diff --git a/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart b/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
index 0f62806..7da792e 100644
--- a/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
@@ -3,17 +3,17 @@
 library engine.instrumentation;
 import 'java_core.dart';
 /**
- * The class {@code Instrumentation} implements support for logging instrumentation information.
- * <p>
+ * The class `Instrumentation` implements support for logging instrumentation information.
+ *
  * 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{@link InstrumentationBuilder instrumentation builder}, created by one of the static methods on
- * this class such as {@link #builder(Class)} or {@link #builder(String)}.
- * <p>
- * Note, however, that until an instrumentation logger is installed using the method{@link #setLogger(InstrumentationLogger)}, all instrumentation data will be lost.
- * <p>
+ * operations, such as tokenizing source code. The information to be logged is gathered by[InstrumentationBuilder instrumentation builder], created by one of the static methods on
+ * this class such as [builder] or [builder].
+ *
+ * Note, however, that until an instrumentation logger is installed using the method[setLogger], all instrumentation data will be lost.
+ *
  * <b>Example</b>
- * <p>
+ *
  * To collect metrics about how long it took to save a file, you would write something like the
  * following:
  * <pre>
@@ -21,9 +21,9 @@
  * // save the file
  * instrumentation.metric("chars", fileLength).log();
  * </pre>
- * The {@code Instrumentation.builder} method creates a new {@link InstrumentationBuilderinstrumentation builder} and records the time at which it was created. The{@link InstrumentationBuilder#metric(String,long)} appends the information specified by the
+ * The `Instrumentation.builder` method creates a new [InstrumentationBuilderinstrumentation builder] and records the time at which it was created. The[InstrumentationBuilder#metric] appends the information specified by the
  * arguments and records the time at which the method is called so that the time to complete the
- * save operation can be calculated. The {@code log} method tells the builder that all of the data
+ * save operation can be calculated. The `log` method tells the builder that all of the data
  * has been collected and that the resulting information should be logged.
  * @coverage dart.engine.utilities
  */
@@ -47,15 +47,15 @@
 
   /**
    * Create a builder that can collect the data associated with an operation.
-   * @param clazz the class performing the operation (not {@code null})
-   * @return the builder that was created (not {@code null})
+   * @param clazz the class performing the operation (not `null`)
+   * @return the builder that was created (not `null`)
    */
   static InstrumentationBuilder builder(Type clazz) => _CURRENT_LOGGER.createBuilder(clazz.toString());
 
   /**
    * Create a builder that can collect the data associated with an operation.
-   * @param name the name used to uniquely identify the operation (not {@code null})
-   * @return the builder that was created (not {@code null})
+   * @param name the name used to uniquely identify the operation (not `null`)
+   * @return the builder that was created (not `null`)
    */
   static InstrumentationBuilder builder2(String name) => _CURRENT_LOGGER.createBuilder(name);
 
@@ -66,7 +66,7 @@
 
   /**
    * Return a builder that will silently ignore all data and logging requests.
-   * @return the builder (not {@code null})
+   * @return the builder (not `null`)
    */
   static InstrumentationBuilder get nullBuilder => _NULL_INSTRUMENTATION_BUILDER;
 
@@ -75,7 +75,7 @@
    * it?
    * @return
    */
-  static bool isNullLogger() => identical(_CURRENT_LOGGER, _NULL_LOGGER);
+  static bool get isNullLogger => identical(_CURRENT_LOGGER, _NULL_LOGGER);
 
   /**
    * Set the logger that should receive instrumentation information to the given logger.
@@ -103,10 +103,10 @@
   InstrumentationBuilder createBuilder(String name) => Instrumentation._NULL_INSTRUMENTATION_BUILDER;
 }
 /**
- * The interface {@code InstrumentationBuilder} defines the behavior of objects used to collect data
+ * The interface `InstrumentationBuilder` 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}.
+ *
+ * For an example of using objects that implement this interface, see [Instrumentation].
  * @coverage dart.engine.utilities
  */
 abstract class InstrumentationBuilder {
@@ -152,8 +152,8 @@
   InstrumentationBuilder data4(String name, List<String> value);
 
   /**
-   * Answer the {@link InstrumentationLevel} of this {@code InstrumentationBuilder}.
-   * @return one of {@link InstrumentationLevel#EVERYTHING}, {@link InstrumentationLevel#METRICS},{@link InstrumentationLevel#OFF}
+   * Answer the [InstrumentationLevel] of this `InstrumentationBuilder`.
+   * @return one of [InstrumentationLevel#EVERYTHING], [InstrumentationLevel#METRICS],[InstrumentationLevel#OFF]
    */
   InstrumentationLevel get instrumentationLevel;
 
@@ -206,17 +206,17 @@
 
   /**
    * Append the given exception to the information being collected by this builder. The exception's
-   * class name is captured using {@link #metric(String,String)}. Other aspects of the exception
+   * class name is captured using [metric]. Other aspects of the exception
    * may contain either user identifiable or contains user intellectual property (but is not
-   * guaranteed to contain either) and thus are captured using the various data methods such as{@link #data(String,String)}.
-   * @param exception the exception (may be {@code null})
+   * guaranteed to contain either) and thus are captured using the various data methods such as[data].
+   * @param exception the exception (may be `null`)
    */
   InstrumentationBuilder record(Exception exception);
 }
 /**
- * The instrumentation recording level representing (1) recording {@link #EVERYTHING} recording of
- * all instrumentation data, (2) recording only {@link #METRICS} information, or (3) recording
- * turned {@link #OFF} in which case nothing is recorded.
+ * The instrumentation recording level representing (1) recording [EVERYTHING] recording of
+ * all instrumentation data, (2) recording only [METRICS] information, or (3) recording
+ * turned [OFF] in which case nothing is recorded.
  * @coverage dart.engine.utilities
  */
 class InstrumentationLevel implements Comparable<InstrumentationLevel> {
@@ -261,10 +261,10 @@
   String toString() => name;
 }
 /**
- * The interface {@code InstrumentationLogger} defines the behavior of objects that are used to log
+ * The interface `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}.
+ *
+ * For an example of using objects that implement this interface, see [Instrumentation].
  * @coverage dart.engine.utilities
  */
 abstract class InstrumentationLogger {
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_core.dart b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
index 7e90245..01ffd5d 100644
--- a/pkg/analyzer_experimental/lib/src/generated/java_core.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
@@ -154,6 +154,16 @@
       }
     });
   }
+  static int indexOf(String target, String str, int fromIndex) {
+    if (fromIndex > target.length) return -1;
+    if (fromIndex < 0) fromIndex = 0;
+    return target.indexOf(str, fromIndex);
+  }
+  static int lastIndexOf(String target, String str, int fromIndex) {
+    if (fromIndex > target.length) return -1;
+    if (fromIndex < 0) fromIndex = 0;
+    return target.lastIndexOf(str, fromIndex);
+  }
   static bool startsWithBefore(String s, String other, int start) {
     return s.indexOf(other, start) != -1;
   }
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_io.dart b/pkg/analyzer_experimental/lib/src/generated/java_io.dart
index b1cced8..fbbe65f 100644
--- a/pkg/analyzer_experimental/lib/src/generated/java_io.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/java_io.dart
@@ -28,7 +28,7 @@
       }
     }
     if (name == 'com.google.dart.sdk') {
-      String exec = new Options().executable;
+      String exec = Platform.executable;
       if (exec.length != 0) {
         String sdkPath;
         // may be "xcodebuild/ReleaseIA32/dart" with "dart-sdk" sibling
diff --git a/pkg/analyzer_experimental/lib/src/generated/parser.dart b/pkg/analyzer_experimental/lib/src/generated/parser.dart
index bd5a1dc..32c04c8 100644
--- a/pkg/analyzer_experimental/lib/src/generated/parser.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/parser.dart
@@ -11,14 +11,14 @@
 import 'ast.dart';
 import 'utilities_dart.dart';
 /**
- * Instances of the class {@code CommentAndMetadata} implement a simple data-holder for a method
+ * Instances of the class `CommentAndMetadata` implement a simple data-holder for a method
  * that needs to return multiple values.
  * @coverage dart.engine.parser
  */
 class CommentAndMetadata {
 
   /**
-   * The documentation comment that was parsed, or {@code null} if none was given.
+   * The documentation comment that was parsed, or `null` if none was given.
    */
   Comment _comment;
 
@@ -38,7 +38,7 @@
   }
 
   /**
-   * Return the documentation comment that was parsed, or {@code null} if none was given.
+   * Return the documentation comment that was parsed, or `null` if none was given.
    * @return the documentation comment that was parsed
    */
   Comment get comment => _comment;
@@ -50,19 +50,19 @@
   List<Annotation> get metadata => _metadata;
 }
 /**
- * Instances of the class {@code FinalConstVarOrType} implement a simple data-holder for a method
+ * Instances of the class `FinalConstVarOrType` implement a simple data-holder for a method
  * that needs to return multiple values.
  * @coverage dart.engine.parser
  */
 class FinalConstVarOrType {
 
   /**
-   * The 'final', 'const' or 'var' keyword, or {@code null} if none was given.
+   * The 'final', 'const' or 'var' keyword, or `null` if none was given.
    */
   Token _keyword;
 
   /**
-   * The type, of {@code null} if no type was specified.
+   * The type, of `null` if no type was specified.
    */
   TypeName _type;
 
@@ -77,103 +77,103 @@
   }
 
   /**
-   * Return the 'final', 'const' or 'var' keyword, or {@code null} if none was given.
+   * Return the 'final', 'const' or 'var' keyword, or `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, of `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
+ * Instances of the class `Modifiers` implement a simple data-holder for a method that needs
  * to return multiple values.
  * @coverage dart.engine.parser
  */
 class Modifiers {
 
   /**
-   * The token representing the keyword 'abstract', or {@code null} if the keyword was not found.
+   * The token representing the keyword 'abstract', or `null` if the keyword was not found.
    */
   Token _abstractKeyword;
 
   /**
-   * The token representing the keyword 'const', or {@code null} if the keyword was not found.
+   * The token representing the keyword 'const', or `null` if the keyword was not found.
    */
   Token _constKeyword;
 
   /**
-   * The token representing the keyword 'external', or {@code null} if the keyword was not found.
+   * The token representing the keyword 'external', or `null` if the keyword was not found.
    */
   Token _externalKeyword;
 
   /**
-   * The token representing the keyword 'factory', or {@code null} if the keyword was not found.
+   * The token representing the keyword 'factory', or `null` if the keyword was not found.
    */
   Token _factoryKeyword;
 
   /**
-   * The token representing the keyword 'final', or {@code null} if the keyword was not found.
+   * The token representing the keyword 'final', or `null` if the keyword was not found.
    */
   Token _finalKeyword;
 
   /**
-   * The token representing the keyword 'static', or {@code null} if the keyword was not found.
+   * The token representing the keyword 'static', or `null` if the keyword was not found.
    */
   Token _staticKeyword;
 
   /**
-   * The token representing the keyword 'var', or {@code null} if the keyword was not found.
+   * The token representing the keyword 'var', or `null` if the keyword was not found.
    */
   Token _varKeyword;
 
   /**
-   * Return the token representing the keyword 'abstract', or {@code null} if the keyword was not
+   * Return the token representing the keyword 'abstract', or `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
+   * Return the token representing the keyword 'const', or `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
+   * Return the token representing the keyword 'external', or `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
+   * Return the token representing the keyword 'factory', or `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
+   * Return the token representing the keyword 'final', or `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
+   * Return the token representing the keyword 'static', or `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', or `null` if the keyword was not found.
    * @return the token representing the keyword 'var'
    */
   Token get varKeyword => _varKeyword;
@@ -246,12 +246,12 @@
   }
 
   /**
-   * If the given keyword is not {@code null}, append it to the given builder, prefixing it with a
+   * If the given keyword is not `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 needsSpace `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
+   * @return `true` if subsequent keywords need to be prefixed with a space
    */
   bool appendKeyword(JavaStringBuilder builder, bool needsSpace, Token keyword) {
     if (keyword != null) {
@@ -265,7 +265,7 @@
   }
 }
 /**
- * Instances of the class {@code Parser} are used to parse tokens into an AST structure.
+ * Instances of the class `Parser` are used to parse tokens into an AST structure.
  * @coverage dart.engine.parser
  */
 class Parser {
@@ -329,7 +329,7 @@
   /**
    * 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
+   * @return the expression that was parsed, or `null` if the tokens do not represent a
    * recognizable expression
    */
   Expression parseExpression(Token token) {
@@ -345,7 +345,7 @@
   /**
    * 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
+   * @return the statement that was parsed, or `null` if the tokens do not represent a
    * recognizable statement
    */
   Statement parseStatement(Token token) {
@@ -361,7 +361,7 @@
   /**
    * 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
+   * @return the statements that were parsed, or `null` if the tokens do not represent a
    * recognizable sequence of statements
    */
   List<Statement> parseStatements(Token token) {
@@ -450,10 +450,10 @@
   FunctionDeclaration convertToFunctionDeclaration(MethodDeclaration method) => new FunctionDeclaration.full(method.documentationComment, method.metadata, method.externalKeyword, method.returnType, method.propertyKeyword, method.name, new FunctionExpression.full(method.parameters, method.body));
 
   /**
-   * Return {@code true} if the current token could be the start of a compilation unit member. This
+   * Return `true` if the current token could be the start of a compilation unit member. This
    * method is used for recovery purposes to decide when to stop skipping tokens after finding an
    * error while parsing a compilation unit member.
-   * @return {@code true} if the current token could be the start of a compilation unit member
+   * @return `true` if the current token could be the start of a compilation unit member
    */
   bool couldBeStartOfCompilationUnitMember() {
     if ((matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword.LIBRARY) || matches(Keyword.PART)) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT)) {
@@ -517,7 +517,7 @@
    * @param expression the expression being checked
    */
   void ensureAssignable(Expression expression) {
-    if (expression != null && !expression.isAssignable()) {
+    if (expression != null && !expression.isAssignable) {
       reportError7(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, []);
     }
   }
@@ -556,7 +556,7 @@
 
   /**
    * Search the given list of ranges for a range that contains the given index. Return the range
-   * that was found, or {@code null} if none of the ranges contain the index.
+   * that was found, or `null` if none of the ranges contain the index.
    * @param ranges the ranges to be searched
    * @param index the index contained in the returned range
    * @return the range that was found
@@ -611,7 +611,7 @@
           index = end;
         }
       } else if (JavaString.startsWithBefore(comment, "[:", index)) {
-        int end = comment.indexOf(":]", index + 2);
+        int end = JavaString.indexOf(comment, ":]", index + 2);
         if (end < 0) {
           end = length;
         }
@@ -625,7 +625,7 @@
   }
 
   /**
-   * Return the end token associated with the given begin token, or {@code null} if either the given
+   * Return the end token associated with the given begin token, or `null` if either the given
    * token is not a begin token or it does not have an end token associated with it.
    * @param beginToken the token that is expected to have an end token associated with it
    * @return the end token associated with the begin token
@@ -638,11 +638,11 @@
   }
 
   /**
-   * Return {@code true} if the current token is the first token of a return type that is followed
+   * Return `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 `true` if we can successfully parse the rest of a type alias if we first parse a
    * return type.
    */
   bool hasReturnTypeInTypeAlias() {
@@ -654,8 +654,8 @@
   }
 
   /**
-   * 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
+   * Return `true` if the current token appears to be the beginning of a function declaration.
+   * @return `true` if the current token appears to be the beginning of a function declaration
    */
   bool isFunctionDeclaration() {
     if (matches(Keyword.VOID)) {
@@ -676,9 +676,9 @@
   }
 
   /**
-   * Return {@code true} if the given token appears to be the beginning of a function expression.
+   * Return `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
+   * @return `true` if the given token appears to be the beginning of a function expression
    */
   bool isFunctionExpression(Token startToken) {
     Token afterParameters = skipFormalParameterList(startToken);
@@ -689,14 +689,14 @@
   }
 
   /**
-   * Return {@code true} if the given character is a valid hexadecimal digit.
+   * Return `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
+   * @return `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
+   * Return `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>
@@ -714,7 +714,7 @@
    * initializedIdentifier ::=
    * identifier ('=' expression)?
    * </pre>
-   * @return {@code true} if the current token is the first token in an initialized variable
+   * @return `true` if the current token is the first token in an initialized variable
    * declaration
    */
   bool isInitializedVariableDeclaration() {
@@ -740,12 +740,12 @@
    * Given that we have just found bracketed text within a comment, look to see whether that text is
    * (a) followed by a parenthesized link address, (b) followed by a colon, or (c) followed by
    * optional whitespace and another square bracket.
-   * <p>
+   *
    * This method uses the syntax described by the <a
    * href="http://daringfireball.net/projects/markdown/syntax">markdown</a> project.
    * @param comment the comment text in which the bracketed text was found
    * @param rightIndex the index of the right bracket
-   * @return {@code true} if the bracketed text is followed by a link address
+   * @return `true` if the bracketed text is followed by a link address
    */
   bool isLinkText(String comment, int rightIndex) {
     int length = comment.length;
@@ -768,14 +768,14 @@
   }
 
   /**
-   * Return {@code true} if the given token appears to be the beginning of an operator declaration.
+   * Return `true` if the given token appears to be the beginning of an operator declaration.
    * @param startToken the token that might be the start of an operator declaration
-   * @return {@code true} if the given token appears to be the beginning of an operator declaration
+   * @return `true` if the given token appears to be the beginning of an operator declaration
    */
   bool isOperator(Token startToken) {
-    if (startToken.isOperator()) {
+    if (startToken.isOperator) {
       Token token = startToken.next;
-      while (token.isOperator()) {
+      while (token.isOperator) {
         token = token.next;
       }
       return matches4(token, TokenType.OPEN_PAREN);
@@ -784,8 +784,8 @@
   }
 
   /**
-   * 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
+   * Return `true` if the current token appears to be the beginning of a switch member.
+   * @return `true` if the current token appears to be the beginning of a switch member
    */
   bool isSwitchMember() {
     Token token = _currentToken;
@@ -801,9 +801,9 @@
 
   /**
    * 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}.
+   * is, return the left-most of all of the tokens. The arguments are allowed to be `null`.
+   * Return the token with the smallest offset, or `null` if there are no arguments or if all
+   * of the arguments are `null`.
    * @param tokens the tokens being compared
    * @return the token with the smallest offset
    */
@@ -823,42 +823,42 @@
   }
 
   /**
-   * Return {@code true} if the current token matches the given keyword.
+   * Return `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
+   * @return `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.
+   * Return `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
+   * @return `true` if the current token matches the given identifier
    */
   bool matches2(String identifier) => identical(_currentToken.type, TokenType.IDENTIFIER) && _currentToken.lexeme == identifier;
 
   /**
-   * Return {@code true} if the given token matches the given keyword.
+   * Return `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
+   * @return `true` if the given token matches the given keyword
    */
   bool matches3(Token token, Keyword keyword2) => identical(token.type, TokenType.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword2);
 
   /**
-   * Return {@code true} if the given token has the given type.
+   * Return `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
+   * @return `true` if the given token has the given type
    */
   bool matches4(Token token, TokenType type2) => identical(token.type, type2);
 
   /**
-   * Return {@code true} if the current token has the given type. Note that this method, unlike
+   * Return `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.
+   * the token stream will be re-written and `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
+   * @return `true` if the current token has the given type
    */
   bool matches5(TokenType type2) {
     TokenType currentType = _currentToken.type;
@@ -901,10 +901,10 @@
   }
 
   /**
-   * Return {@code true} if the given token has any one of the given types.
+   * Return `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
+   * @return `true` if the given token has any of the given types
    */
   bool matchesAny(Token token, List<TokenType> types) {
     TokenType actualType = token.type;
@@ -917,23 +917,23 @@
   }
 
   /**
-   * Return {@code true} if the current token is a valid identifier. Valid identifiers include
+   * Return `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
+   * @return `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
+   * Return `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
+   * @return `true` if the given token is a valid identifier
    */
-  bool matchesIdentifier2(Token token) => matches4(token, TokenType.IDENTIFIER) || (matches4(token, TokenType.KEYWORD) && ((token as KeywordToken)).keyword.isPseudoKeyword());
+  bool matchesIdentifier2(Token token) => matches4(token, TokenType.IDENTIFIER) || (matches4(token, TokenType.KEYWORD) && ((token as KeywordToken)).keyword.isPseudoKeyword);
 
   /**
-   * If the current token has the given type, then advance to the next token and return {@code true}. Otherwise, return {@code false} without advancing.
+   * If the current token has the given type, then advance to the next token and return `true`. Otherwise, return `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
+   * @return `true` if the current token has the given type
    */
   bool optional(TokenType type) {
     if (matches5(type)) {
@@ -954,12 +954,12 @@
    */
   Expression parseAdditiveExpression() {
     Expression expression;
-    if (matches(Keyword.SUPER) && _currentToken.next.type.isAdditiveOperator()) {
+    if (matches(Keyword.SUPER) && _currentToken.next.type.isAdditiveOperator) {
       expression = new SuperExpression.full(andAdvance);
     } else {
       expression = parseMultiplicativeExpression();
     }
-    while (_currentToken.type.isAdditiveOperator()) {
+    while (_currentToken.type.isAdditiveOperator) {
       Token operator = andAdvance;
       expression = new BinaryExpression.full(expression, operator, parseMultiplicativeExpression());
     }
@@ -1087,7 +1087,7 @@
    * | 'super' assignableSelector
    * | identifier
    * </pre>
-   * @param primaryAllowed {@code true} if the expression is allowed to be a primary without any
+   * @param primaryAllowed `true` if the expression is allowed to be a primary without any
    * assignable selector
    * @return the assignable expression that was parsed
    */
@@ -1136,7 +1136,7 @@
    * | '.' identifier
    * </pre>
    * @param prefix the expression preceding the selector
-   * @param optional {@code true} if the selector is optional
+   * @param optional `true` if the selector is optional
    * @return the assignable selector that was parsed
    */
   Expression parseAssignableSelector(Expression prefix, bool optional) {
@@ -1330,7 +1330,7 @@
         }
       }
     }
-    if (_currentToken.type.isAssignmentOperator()) {
+    if (_currentToken.type.isAssignmentOperator) {
       Token operator = andAdvance;
       ensureAssignable(expression);
       expression = new AssignmentExpression.full(expression, operator, parseExpressionWithoutCascade());
@@ -1345,7 +1345,7 @@
    * 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
+   * @param abstractKeyword the token for the keyword 'abstract', or `null` if the keyword was
    * not given
    * @return the class declaration that was parsed
    */
@@ -1425,7 +1425,7 @@
    * | methodSignature functionBody
    * </pre>
    * @param className the name of the class containing the member being parsed
-   * @return the class member that was parsed, or {@code null} if what was found was not a valid
+   * @return the class member that was parsed, or `null` if what was found was not a valid
    * class member
    */
   ClassMember parseClassMember(String className) {
@@ -1533,7 +1533,7 @@
    * (metadata memberDefinition)
    * </pre>
    * @param className the name of the class whose members are being parsed
-   * @param closingBracket the closing bracket for the class, or {@code null} if the closing bracket
+   * @param closingBracket the closing bracket for the class, or `null` if the closing bracket
    * is missing
    * @return the list of class members that were parsed
    */
@@ -1664,7 +1664,7 @@
    * @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, or {@code null} if no reference could be found
+   * @return the comment reference that was parsed, or `null` if no reference could be found
    */
   CommentReference parseCommentReference(String referenceSource, int sourceOffset) {
     if (referenceSource.length == 0) {
@@ -1729,7 +1729,7 @@
       while (leftIndex >= 0 && leftIndex + 1 < length) {
         List<int> range = findRange(codeBlockRanges, leftIndex);
         if (range == null) {
-          int rightIndex = comment.indexOf(']', leftIndex);
+          int rightIndex = JavaString.indexOf(comment, ']', leftIndex);
           if (rightIndex >= 0) {
             int firstChar = comment.codeUnitAt(leftIndex + 1);
             if (firstChar != 0x27 && firstChar != 0x22) {
@@ -1744,9 +1744,9 @@
           } else {
             rightIndex = leftIndex + 1;
           }
-          leftIndex = comment.indexOf('[', rightIndex);
+          leftIndex = JavaString.indexOf(comment, '[', rightIndex);
         } else {
-          leftIndex = comment.indexOf('[', range[1] + 1);
+          leftIndex = JavaString.indexOf(comment, '[', range[1] + 1);
         }
       }
     }
@@ -1755,7 +1755,7 @@
 
   /**
    * Parse a compilation unit.
-   * <p>
+   *
    * Specified:
    * <pre>
    * compilationUnit ::=
@@ -1861,7 +1861,7 @@
    * | variableDeclaration ';'
    * </pre>
    * @param commentAndMetadata the metadata to be associated with the member
-   * @return the compilation unit member that was parsed, or {@code null} if what was parsed could
+   * @return the compilation unit member that was parsed, or `null` if what was parsed could
    * not be represented as a compilation unit member
    */
   CompilationUnitMember parseCompilationUnitMember(CommentAndMetadata commentAndMetadata) {
@@ -2129,7 +2129,7 @@
    * multiLineComment?
    * | singleLineComment
    * </pre>
-   * @return the documentation comment that was parsed, or {@code null} if there was no comment
+   * @return the documentation comment that was parsed, or `null` if there was no comment
    */
   Comment parseDocumentationComment() {
     List<Token> commentTokens = new List<Token>();
@@ -2204,12 +2204,12 @@
    */
   Expression parseEqualityExpression() {
     Expression expression;
-    if (matches(Keyword.SUPER) && _currentToken.next.type.isEqualityOperator()) {
+    if (matches(Keyword.SUPER) && _currentToken.next.type.isEqualityOperator) {
       expression = new SuperExpression.full(andAdvance);
     } else {
       expression = parseRelationalExpression();
     }
-    while (_currentToken.type.isEqualityOperator()) {
+    while (_currentToken.type.isEqualityOperator) {
       Token operator = andAdvance;
       expression = new BinaryExpression.full(expression, operator, parseRelationalExpression());
     }
@@ -2261,7 +2261,7 @@
         tokenType = _currentToken.type;
       }
       return new CascadeExpression.full(expression, cascadeSections);
-    } else if (tokenType.isAssignmentOperator()) {
+    } else if (tokenType.isAssignmentOperator) {
       Token operator = andAdvance;
       ensureAssignable(expression);
       return new AssignmentExpression.full(expression, operator, parseExpression2());
@@ -2303,7 +2303,7 @@
       return parseRethrowExpression();
     }
     Expression expression = parseConditionalExpression();
-    if (_currentToken.type.isAssignmentOperator()) {
+    if (_currentToken.type.isAssignmentOperator) {
       Token operator = andAdvance;
       ensureAssignable(expression);
       expression = new AssignmentExpression.full(expression, operator, parseExpressionWithoutCascade());
@@ -2334,7 +2334,7 @@
    * | 'var'
    * | type
    * </pre>
-   * @param optional {@code true} if the keyword and type are optional
+   * @param optional `true` if the keyword and type are optional
    * @return the 'final', 'const', 'var' or type that was parsed
    */
   FinalConstVarOrType parseFinalConstVarOrType(bool optional) {
@@ -2358,7 +2358,7 @@
   }
 
   /**
-   * Parse a formal parameter. At most one of {@code isOptional} and {@code isNamed} can be{@code true}.
+   * Parse a formal parameter. At most one of `isOptional` and `isNamed` can be`true`.
    * <pre>
    * defaultFormalParameter ::=
    * normalFormalParameter ('=' expression)?
@@ -2603,9 +2603,9 @@
    * '=>' expression
    * | block
    * </pre>
-   * @param mayBeEmpty {@code true} if the function body is allowed to be empty
+   * @param mayBeEmpty `true` if the function body is allowed to be empty
    * @param emptyErrorCode the error code to report if function body expecte, but not found
-   * @param inExpression {@code true} if the function body is being parsed as part of an expression
+   * @param inExpression `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
    */
@@ -2656,9 +2656,9 @@
    * </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
+   * @param externalKeyword the 'external' keyword, or `null` if the function is not external
+   * @param returnType the return type, or `null` if there is no return type
+   * @param isStatement `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) {
@@ -2710,7 +2710,7 @@
    * </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
+   * @param returnType the return type, or `null` if there is no return type
    * @return the function declaration statement that was parsed
    */
   Statement parseFunctionDeclarationStatement2(CommentAndMetadata commentAndMetadata, TypeName returnType) => new FunctionDeclarationStatement.full(parseFunctionDeclaration(commentAndMetadata, null, returnType));
@@ -2778,8 +2778,8 @@
    * @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
+   * @param staticKeyword the static keyword, or `null` if the getter is not static
+   * @param the return type that has already been parsed, or `null` if there was no return
    * type
    * @return the getter that was parsed
    */
@@ -2893,10 +2893,10 @@
    * </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
+   * @param staticKeyword the static keyword, or `null` if the getter is not static
+   * @param keyword the token representing the 'final', 'const' or 'var' keyword, or `null` if
    * there is no keyword
-   * @param type the type that has already been parsed, or {@code null} if 'var' was provided
+   * @param type the type that has already been parsed, or `null` if 'var' was provided
    * @return the getter that was parsed
    */
   FieldDeclaration parseInitializedIdentifierList(CommentAndMetadata commentAndMetadata, Token staticKeyword, Token keyword, TypeName type) {
@@ -2984,9 +2984,9 @@
    * listLiteral ::=
    * 'const'? typeArguments? '\[' (expressionList ','?)? '\]'
    * </pre>
-   * @param modifier the 'const' modifier appearing before the literal, or {@code null} if there is
+   * @param modifier the 'const' modifier appearing before the literal, or `null` if there is
    * no modifier
-   * @param typeArguments the type arguments appearing before the literal, or {@code null} if there
+   * @param typeArguments the type arguments appearing before the literal, or `null` if there
    * are no type arguments
    * @return the list literal that was parsed
    */
@@ -3024,7 +3024,7 @@
    * listLiteral
    * | mapLiteral
    * </pre>
-   * @param modifier the 'const' modifier appearing before the literal, or {@code null} if there is
+   * @param modifier the 'const' modifier appearing before the literal, or `null` if there is
    * no modifier
    * @return the list or map literal that was parsed
    */
@@ -3082,9 +3082,9 @@
    * mapLiteral ::=
    * 'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
    * </pre>
-   * @param modifier the 'const' modifier appearing before the literal, or {@code null} if there is
+   * @param modifier the 'const' modifier appearing before the literal, or `null` if there is
    * no modifier
-   * @param typeArguments the type arguments that were declared, or {@code null} if there are no
+   * @param typeArguments the type arguments that were declared, or `null` if there are no
    * type arguments
    * @return the map literal that was parsed
    */
@@ -3136,7 +3136,7 @@
    * @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 staticKeyword the static keyword, or `null` if the getter is not static
    * @param returnType the return type of the method
    * @return the method declaration that was parsed
    */
@@ -3157,7 +3157,7 @@
    * @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 staticKeyword the static keyword, or `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
@@ -3181,7 +3181,7 @@
    * 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}.
+   * reported in one of the methods whose name is prefixed with `validateModifiersFor`.
    * <pre>
    * modifiers ::=
    * ('abstract' | 'const' | 'external' | 'factory' | 'final' | 'static' | 'var')
@@ -3259,12 +3259,12 @@
    */
   Expression parseMultiplicativeExpression() {
     Expression expression;
-    if (matches(Keyword.SUPER) && _currentToken.next.type.isMultiplicativeOperator()) {
+    if (matches(Keyword.SUPER) && _currentToken.next.type.isMultiplicativeOperator) {
       expression = new SuperExpression.full(andAdvance);
     } else {
       expression = parseUnaryExpression();
     }
-    while (_currentToken.type.isMultiplicativeOperator()) {
+    while (_currentToken.type.isMultiplicativeOperator) {
       Token operator = andAdvance;
       expression = new BinaryExpression.full(expression, operator, parseUnaryExpression());
     }
@@ -3312,7 +3312,7 @@
         }
       }
       return parseBlock();
-    } else if (matches5(TokenType.KEYWORD) && !((_currentToken as KeywordToken)).keyword.isPseudoKeyword()) {
+    } else if (matches5(TokenType.KEYWORD) && !((_currentToken as KeywordToken)).keyword.isPseudoKeyword) {
       Keyword keyword = ((_currentToken as KeywordToken)).keyword;
       if (identical(keyword, Keyword.ASSERT)) {
         return parseAssertStatement();
@@ -3442,7 +3442,7 @@
    * @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
+   * @param the return type that has already been parsed, or `null` if there was no return
    * type
    * @return the operator declaration that was parsed
    */
@@ -3454,7 +3454,7 @@
       reportError8(ParserErrorCode.MISSING_KEYWORD_OPERATOR, _currentToken, []);
       operatorKeyword = createSyntheticToken(Keyword.OPERATOR);
     }
-    if (!_currentToken.isUserDefinableOperator()) {
+    if (!_currentToken.isUserDefinableOperator) {
       reportError7(ParserErrorCode.NON_USER_DEFINABLE_OPERATOR, [_currentToken.lexeme]);
     }
     SimpleIdentifier name = new SimpleIdentifier.full(andAdvance);
@@ -3475,7 +3475,7 @@
   }
 
   /**
-   * Parse a return type if one is given, otherwise return {@code null} without advancing.
+   * Parse a return type if one is given, otherwise return `null` without advancing.
    * @return the return type that was parsed
    */
   TypeName parseOptionalReturnType() {
@@ -3543,7 +3543,7 @@
       } while (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.PERIOD) || matches5(TokenType.OPEN_PAREN));
       return operand;
     }
-    if (!_currentToken.type.isIncrementOperator()) {
+    if (!_currentToken.type.isIncrementOperator) {
       return operand;
     }
     if (operand is FunctionExpressionInvocation) {
@@ -3693,7 +3693,7 @@
    * @return the relational expression that was parsed
    */
   Expression parseRelationalExpression() {
-    if (matches(Keyword.SUPER) && _currentToken.next.type.isRelationalOperator()) {
+    if (matches(Keyword.SUPER) && _currentToken.next.type.isRelationalOperator) {
       Expression expression = new SuperExpression.full(andAdvance);
       Token operator = andAdvance;
       expression = new BinaryExpression.full(expression, operator, parseShiftExpression());
@@ -3710,7 +3710,7 @@
         notOperator = andAdvance;
       }
       expression = new IsExpression.full(expression, isOperator, notOperator, parseTypeName());
-    } else if (_currentToken.type.isRelationalOperator()) {
+    } else if (_currentToken.type.isRelationalOperator) {
       Token operator = andAdvance;
       expression = new BinaryExpression.full(expression, operator, parseShiftExpression());
     }
@@ -3773,8 +3773,8 @@
    * @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
+   * @param staticKeyword the static keyword, or `null` if the setter is not static
+   * @param the return type that has already been parsed, or `null` if there was no return
    * type
    * @return the setter that was parsed
    */
@@ -3801,12 +3801,12 @@
    */
   Expression parseShiftExpression() {
     Expression expression;
-    if (matches(Keyword.SUPER) && _currentToken.next.type.isShiftOperator()) {
+    if (matches(Keyword.SUPER) && _currentToken.next.type.isShiftOperator) {
       expression = new SuperExpression.full(andAdvance);
     } else {
       expression = parseAdditiveExpression();
     }
-    while (_currentToken.type.isShiftOperator()) {
+    while (_currentToken.type.isShiftOperator) {
       Token operator = andAdvance;
       expression = new BinaryExpression.full(expression, operator, parseAdditiveExpression());
     }
@@ -4256,7 +4256,7 @@
         return new PrefixExpression.full(operator, new SuperExpression.full(andAdvance));
       }
       return new PrefixExpression.full(operator, parseUnaryExpression());
-    } else if (_currentToken.type.isIncrementOperator()) {
+    } else if (_currentToken.type.isIncrementOperator) {
       Token operator = andAdvance;
       if (matches(Keyword.SUPER)) {
         if (matches4(peek(), TokenType.OPEN_SQUARE_BRACKET) || matches4(peek(), TokenType.PERIOD)) {
@@ -4323,8 +4323,8 @@
    * variableDeclarationList ::=
    * finalConstVarOrType variableDeclaration (',' variableDeclaration)
    * </pre>
-   * @param commentAndMetadata the metadata to be associated with the variable declaration list, or{@code null} if there is no attempt at parsing the comment and metadata
-   * @param keyword the token representing the 'final', 'const' or 'var' keyword, or {@code null} if
+   * @param commentAndMetadata the metadata to be associated with the variable declaration list, or`null` if there is no attempt at parsing the comment and metadata
+   * @param keyword the token representing the 'final', 'const' or 'var' keyword, or `null` if
    * there is no keyword
    * @param type the type of the variables in the list
    * @return the variable declaration list that was parsed
@@ -4346,7 +4346,7 @@
    * variableDeclarationList ';'
    * </pre>
    * @param commentAndMetadata the metadata to be associated with the variable declaration
-   * statement, or {@code null} if there is no attempt at parsing the comment and metadata
+   * statement, or `null` if there is no attempt at parsing the comment and metadata
    * @return the variable declaration statement that was parsed
    */
   VariableDeclarationStatement parseVariableDeclarationStatement(CommentAndMetadata commentAndMetadata) {
@@ -4362,8 +4362,8 @@
    * variableDeclarationList ';'
    * </pre>
    * @param commentAndMetadata the metadata to be associated with the variable declaration
-   * statement, or {@code null} if there is no attempt at parsing the comment and metadata
-   * @param keyword the token representing the 'final', 'const' or 'var' keyword, or {@code null} if
+   * statement, or `null` if there is no attempt at parsing the comment and metadata
+   * @param keyword the token representing the 'final', 'const' or 'var' keyword, or `null` if
    * there is no keyword
    * @param type the type of the variables in the list
    * @return the variable declaration statement that was parsed
@@ -4416,14 +4416,14 @@
   }
 
   /**
-   * 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. This is equivalent to[peek].
    * @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.
+   * @param distance the number of tokens to look ahead, where `0` is the current token,`1` is the next token, etc.
    * @return the token that is the given distance after the current token
    */
   Token peek2(int distance) {
@@ -4466,7 +4466,7 @@
   /**
    * 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
+   * following the type that was parsed, or `null` if the given token is not the first token
    * in a valid type.
    * <pre>
    * finalConstVarOrType ::=
@@ -4498,16 +4498,16 @@
   /**
    * 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
+   * parameter list that was parsed, or `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()}.
+   *
+   * This method must be kept in sync with [parseFormalParameterList].
    * <pre>
    * formalParameterList ::=
    * '(' ')'
@@ -4555,7 +4555,7 @@
 
   /**
    * 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}.
+   * following the end token. Otherwise, return `null`.
    * @param startToken the token that is assumed to be a being token
    * @return the token following the matching end token
    */
@@ -4573,10 +4573,10 @@
   /**
    * 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
+   * that was parsed, or `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()}.
+   *
+   * This method must be kept in sync with [parsePrefixedIdentifier].
    * <pre>
    * prefixedIdentifier ::=
    * identifier ('.' identifier)?
@@ -4596,9 +4596,9 @@
 
   /**
    * 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()}.
+   * changing the current token. Return the token following the return type that was parsed, or`null` if the given token is not the first token in a valid return type.
+   *
+   * This method must be kept in sync with [parseReturnType].
    * <pre>
    * returnType ::=
    * 'void'
@@ -4618,10 +4618,10 @@
   /**
    * 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
+   * was parsed, or `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()}.
+   *
+   * This method must be kept in sync with [parseSimpleIdentifier].
    * <pre>
    * identifier ::=
    * IDENTIFIER
@@ -4630,7 +4630,7 @@
    * @return the token following the simple identifier that was parsed
    */
   Token skipSimpleIdentifier(Token startToken) {
-    if (matches4(startToken, TokenType.IDENTIFIER) || (matches4(startToken, TokenType.KEYWORD) && ((startToken as KeywordToken)).keyword.isPseudoKeyword())) {
+    if (matches4(startToken, TokenType.IDENTIFIER) || (matches4(startToken, TokenType.KEYWORD) && ((startToken as KeywordToken)).keyword.isPseudoKeyword)) {
       return startToken.next;
     }
     return null;
@@ -4639,10 +4639,10 @@
   /**
    * 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
+   * the string literal that was parsed, or `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)}.
+   *
+   * This method must be kept in sync with [parseStringInterpolation].
    * @param startToken the token at which parsing is to begin
    * @return the string literal that was parsed
    */
@@ -4692,9 +4692,9 @@
   /**
    * 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()}.
+   * or `null` if the given token is not the first token in a valid string literal.
+   *
+   * This method must be kept in sync with [parseStringLiteral].
    * <pre>
    * stringLiteral ::=
    * MULTI_LINE_STRING+
@@ -4721,9 +4721,9 @@
   /**
    * 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()}.
+   * or `null` if the given token is not the first token in a valid type argument list.
+   *
+   * This method must be kept in sync with [parseTypeArgumentList].
    * <pre>
    * typeArguments ::=
    * '<' typeList '>'
@@ -4760,9 +4760,9 @@
 
   /**
    * 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()}.
+   * changing the current token. Return the token following the type name that was parsed, or`null` if the given token is not the first token in a valid type name.
+   *
+   * This method must be kept in sync with [parseTypeName].
    * <pre>
    * type ::=
    * qualified typeArguments?
@@ -4784,10 +4784,10 @@
   /**
    * 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
+   * list that was parsed, or `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()}.
+   *
+   * This method must be kept in sync with [parseTypeParameterList].
    * <pre>
    * typeParameterList ::=
    * '<' typeParameter (',' typeParameter)* '>'
@@ -5199,7 +5199,7 @@
   }
 }
 /**
- * The enumeration {@code ParserErrorCode} defines the error codes used for errors detected by the
+ * The enumeration `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.
@@ -5530,7 +5530,7 @@
       for (String line in StringUtils.split(token.lexeme, "\n")) {
         if (firstLine) {
           firstLine = false;
-          if (node.isDocumentation()) {
+          if (node.isDocumentation) {
             nl2();
           }
         } else {
@@ -5790,7 +5790,7 @@
     return null;
   }
   Object visitIndexExpression(IndexExpression node) {
-    if (node.isCascaded()) {
+    if (node.isCascaded) {
       _writer.print("..");
     } else {
       visit(node.array);
@@ -5892,7 +5892,7 @@
     visit8(node.propertyKeyword, " ");
     visit8(node.operatorKeyword, " ");
     visit(node.name);
-    if (!node.isGetter()) {
+    if (!node.isGetter) {
       visit(node.parameters);
     }
     if (node.body is! EmptyFunctionBody) {
@@ -5902,7 +5902,7 @@
     return null;
   }
   Object visitMethodInvocation(MethodInvocation node) {
-    if (node.isCascaded()) {
+    if (node.isCascaded) {
       _writer.print("..");
     } else {
       visit6(node.target, ".");
@@ -5961,7 +5961,7 @@
     return null;
   }
   Object visitPropertyAccess(PropertyAccess node) {
-    if (node.isCascaded()) {
+    if (node.isCascaded) {
       _writer.print("..");
     } else {
       visit6(node.target, ".");
diff --git a/pkg/analyzer_experimental/lib/src/generated/resolver.dart b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
index 3a052ac..dc5fb59 100644
--- a/pkg/analyzer_experimental/lib/src/generated/resolver.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
@@ -17,7 +17,7 @@
 import 'engine.dart';
 import 'constant.dart';
 /**
- * Instances of the class {@code CompilationUnitBuilder} build an element model for a single
+ * Instances of the class `CompilationUnitBuilder` build an element model for a single
  * compilation unit.
  * @coverage dart.engine.resolver
  */
@@ -49,7 +49,7 @@
   }
 }
 /**
- * Instances of the class {@code ElementBuilder} traverse an AST structure and build the element
+ * Instances of the class `ElementBuilder` traverse an AST structure and build the element
  * model representing the AST structure.
  * @coverage dart.engine.resolver
  */
@@ -76,6 +76,13 @@
   bool _isValidMixin = false;
 
   /**
+   * A collection holding the function types defined in a class that need to have their type
+   * arguments set to the types of the type parameters for the class, or `null` if we are not
+   * currently processing nodes within a class.
+   */
+  List<FunctionTypeImpl> _functionTypesToFix = null;
+
+  /**
    * Initialize a newly created element builder to build the elements for a compilation unit.
    * @param initialHolder the element holder associated with the compilation unit being built
    */
@@ -110,12 +117,14 @@
   Object visitClassDeclaration(ClassDeclaration node) {
     ElementHolder holder = new ElementHolder();
     _isValidMixin = true;
+    _functionTypesToFix = new List<FunctionTypeImpl>();
     visitChildren(holder, node);
     SimpleIdentifier className = node.name;
     ClassElementImpl element = new ClassElementImpl(className);
     List<TypeVariableElement> typeVariables = holder.typeVariables;
+    List<Type2> typeArguments = createTypeVariableTypes(typeVariables);
     InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
-    interfaceType.typeArguments = createTypeVariableTypes(typeVariables);
+    interfaceType.typeArguments = typeArguments;
     element.type = interfaceType;
     List<ConstructorElement> constructors = holder.constructors;
     if (constructors.length == 0) {
@@ -128,12 +137,18 @@
     element.methods = holder.methods;
     element.typeVariables = typeVariables;
     element.validMixin = _isValidMixin;
+    for (FunctionTypeImpl functionType in _functionTypesToFix) {
+      functionType.typeArguments = typeArguments;
+    }
+    _functionTypesToFix = null;
     _currentHolder.addType(element);
     className.element = element;
+    holder.validate();
     return null;
   }
   Object visitClassTypeAlias(ClassTypeAlias node) {
     ElementHolder holder = new ElementHolder();
+    _functionTypesToFix = new List<FunctionTypeImpl>();
     visitChildren(holder, node);
     SimpleIdentifier className = node.name;
     ClassElementImpl element = new ClassElementImpl(className);
@@ -141,12 +156,18 @@
     element.typedef = true;
     List<TypeVariableElement> typeVariables = holder.typeVariables;
     element.typeVariables = typeVariables;
+    List<Type2> typeArguments = createTypeVariableTypes(typeVariables);
     InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
-    interfaceType.typeArguments = createTypeVariableTypes(typeVariables);
+    interfaceType.typeArguments = typeArguments;
     element.type = interfaceType;
     element.constructors = createDefaultConstructors(interfaceType);
+    for (FunctionTypeImpl functionType in _functionTypesToFix) {
+      functionType.typeArguments = typeArguments;
+    }
+    _functionTypesToFix = null;
     _currentHolder.addType(element);
     className.element = element;
+    holder.validate();
     return null;
   }
   Object visitConstructorDeclaration(ConstructorDeclaration node) {
@@ -179,6 +200,7 @@
     } else {
       constructorName.element = element;
     }
+    holder.validate();
     return null;
   }
   Object visitDeclaredIdentifier(DeclaredIdentifier node) {
@@ -205,15 +227,13 @@
     initializer.parameters = holder.parameters;
     SimpleIdentifier parameterName = node.parameter.identifier;
     ParameterElementImpl parameter;
-    if (node.isConst()) {
-      parameter = new ConstParameterElementImpl(parameterName);
-      parameter.const3 = true;
-    } else if (node.parameter is FieldFormalParameter) {
-      parameter = new FieldFormalParameterElementImpl(parameterName);
+    if (node.parameter is FieldFormalParameter) {
+      parameter = new DefaultFieldFormalParameterElementImpl(parameterName);
     } else {
-      parameter = new ParameterElementImpl(parameterName);
+      parameter = new DefaultParameterElementImpl(parameterName);
     }
-    parameter.final2 = node.isFinal();
+    parameter.const3 = node.isConst;
+    parameter.final2 = node.isFinal;
     parameter.initializer = initializer;
     parameter.parameterKind = node.kind;
     Expression defaultValue = node.defaultValue;
@@ -227,6 +247,7 @@
     _currentHolder.addParameter(parameter);
     parameterName.element = parameter;
     node.parameter.accept(this);
+    holder.validate();
     return null;
   }
   Object visitFieldDeclaration(FieldDeclaration node) {
@@ -243,8 +264,8 @@
     if (node.parent is! DefaultFormalParameter) {
       SimpleIdentifier parameterName = node.identifier;
       FieldFormalParameterElementImpl parameter = new FieldFormalParameterElementImpl(parameterName);
-      parameter.const3 = node.isConst();
-      parameter.final2 = node.isFinal();
+      parameter.const3 = node.isConst;
+      parameter.final2 = node.isFinal;
       parameter.parameterKind = node.kind;
       _currentHolder.addParameter(parameter);
       parameterName.element = parameter;
@@ -270,8 +291,6 @@
         element.labels = holder.labels;
         element.localVariables = holder.localVariables;
         element.parameters = holder.parameters;
-        FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
-        element.type = type;
         _currentHolder.addFunction(element);
         expression.element = element;
         functionName.element = element;
@@ -314,6 +333,7 @@
           propertyNameNode.element = setter;
         }
       }
+      holder.validate();
     }
     return null;
   }
@@ -340,9 +360,13 @@
       }
     }
     FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
+    if (_functionTypesToFix != null) {
+      _functionTypesToFix.add(type);
+    }
     element.type = type;
     _currentHolder.addFunction(element);
     node.element = element;
+    holder.validate();
     return null;
   }
   Object visitFunctionTypeAlias(FunctionTypeAlias node) {
@@ -359,6 +383,7 @@
     element.type = type;
     _currentHolder.addTypeAlias(element);
     aliasName.element = element;
+    holder.validate();
     return null;
   }
   Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
@@ -372,6 +397,7 @@
     ElementHolder holder = new ElementHolder();
     visitChildren(holder, node);
     ((node.element as ParameterElementImpl)).parameters = holder.parameters;
+    holder.validate();
     return null;
   }
   Object visitLabeledStatement(LabeledStatement node) {
@@ -393,7 +419,7 @@
     } finally {
       _inFunction = wasInFunction;
     }
-    bool isStatic = node.isStatic();
+    bool isStatic = node.isStatic;
     sc.Token property = node.propertyKeyword;
     if (property == null) {
       SimpleIdentifier methodName = node.name;
@@ -402,7 +428,7 @@
         nameOfMethod = "unary-";
       }
       MethodElementImpl element = new MethodElementImpl.con2(nameOfMethod, methodName.offset);
-      element.abstract = node.isAbstract();
+      element.abstract = node.isAbstract;
       element.functions = holder.functions;
       element.labels = holder.labels;
       element.localVariables = holder.localVariables;
@@ -448,14 +474,15 @@
         propertyNameNode.element = setter;
       }
     }
+    holder.validate();
     return null;
   }
   Object visitSimpleFormalParameter(SimpleFormalParameter node) {
     if (node.parent is! DefaultFormalParameter) {
       SimpleIdentifier parameterName = node.identifier;
       ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
-      parameter.const3 = node.isConst();
-      parameter.final2 = node.isFinal();
+      parameter.const3 = node.isConst;
+      parameter.final2 = node.isFinal;
       parameter.parameterKind = node.kind;
       _currentHolder.addParameter(parameter);
       parameterName.element = parameter;
@@ -554,6 +581,7 @@
       initializer.localVariables = holder.localVariables;
       initializer.synthetic = true;
       element.initializer = initializer;
+      holder.validate();
     }
     if (element is PropertyInducingElementImpl) {
       PropertyInducingElementImpl variable = element as PropertyInducingElementImpl;
@@ -562,13 +590,13 @@
       }
       PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(variable);
       getter.getter = true;
-      getter.static = variable.isStatic();
+      getter.static = variable.isStatic;
       _currentHolder.addAccessor(getter);
       variable.getter = getter;
       if (!isFinal) {
         PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(variable);
         setter.setter = true;
-        setter.static = variable.isStatic();
+        setter.static = variable.isStatic;
         _currentHolder.addAccessor(setter);
         variable.setter = setter;
       }
@@ -577,18 +605,26 @@
   }
 
   /**
-   * Creates the {@link ConstructorElement}s array with the single default constructor element.
+   * Creates the [ConstructorElement]s array with the single default constructor element.
    * @param interfaceType the interface type for which to create a default constructor
-   * @return the {@link ConstructorElement}s array with the single default constructor element
+   * @return the [ConstructorElement]s array with the single default constructor element
    */
   List<ConstructorElement> createDefaultConstructors(InterfaceTypeImpl interfaceType) {
     ConstructorElementImpl constructor = new ConstructorElementImpl(null);
     constructor.synthetic = true;
+    constructor.returnType = interfaceType;
     FunctionTypeImpl type = new FunctionTypeImpl.con1(constructor);
-    type.returnType = interfaceType;
+    _functionTypesToFix.add(type);
     constructor.type = type;
     return <ConstructorElement> [constructor];
   }
+
+  /**
+   * Create the types associated with the given type variables, setting the type of each type
+   * variable, and return an array of types corresponding to the given variables.
+   * @param typeVariables the type variables for which types are to be created
+   * @return
+   */
   List<Type2> createTypeVariableTypes(List<TypeVariableElement> typeVariables) {
     int typeVariableCount = typeVariables.length;
     List<Type2> typeArguments = new List<Type2>(typeVariableCount);
@@ -602,7 +638,7 @@
   }
 
   /**
-   * Return the body of the function that contains the given parameter, or {@code null} if no
+   * Return the body of the function that contains the given parameter, or `null` if no
    * function body could be found.
    * @param node the parameter contained in the function whose body is to be returned
    * @return the body of the function that contains the given parameter
@@ -621,10 +657,10 @@
   }
 
   /**
-   * Return {@code true} if the given token is a token for the given keyword.
+   * Return `true` if the given token is a token for the given keyword.
    * @param token the token being tested
    * @param keyword the keyword being tested for
-   * @return {@code true} if the given token is a token for the given keyword
+   * @return `true` if the given token is a token for the given keyword
    */
   bool matches(sc.Token token, sc.Keyword keyword2) => token != null && identical(token.type, sc.TokenType.KEYWORD) && identical(((token as sc.KeywordToken)).keyword, keyword2);
 
@@ -663,72 +699,115 @@
   }
 }
 /**
- * Instances of the class {@code ElementHolder} hold on to elements created while traversing an AST
+ * Instances of the class `ElementHolder` hold on to elements created while traversing an AST
  * structure so that they can be accessed when creating their enclosing element.
  * @coverage dart.engine.resolver
  */
 class ElementHolder {
-  List<PropertyAccessorElement> _accessors = new List<PropertyAccessorElement>();
-  List<ConstructorElement> _constructors = new List<ConstructorElement>();
-  List<FieldElement> _fields = new List<FieldElement>();
-  List<FunctionElement> _functions = new List<FunctionElement>();
-  List<LabelElement> _labels = new List<LabelElement>();
-  List<VariableElement> _localVariables = new List<VariableElement>();
-  List<MethodElement> _methods = new List<MethodElement>();
-  List<FunctionTypeAliasElement> _typeAliases = new List<FunctionTypeAliasElement>();
-  List<ParameterElement> _parameters = new List<ParameterElement>();
-  List<VariableElement> _topLevelVariables = new List<VariableElement>();
-  List<ClassElement> _types = new List<ClassElement>();
-  List<TypeVariableElement> _typeVariables = new List<TypeVariableElement>();
+  List<PropertyAccessorElement> _accessors;
+  List<ConstructorElement> _constructors;
+  List<FieldElement> _fields;
+  List<FunctionElement> _functions;
+  List<LabelElement> _labels;
+  List<VariableElement> _localVariables;
+  List<MethodElement> _methods;
+  List<ParameterElement> _parameters;
+  List<VariableElement> _topLevelVariables;
+  List<ClassElement> _types;
+  List<FunctionTypeAliasElement> _typeAliases;
+  List<TypeVariableElement> _typeVariables;
   void addAccessor(PropertyAccessorElement element) {
+    if (_accessors == null) {
+      _accessors = new List<PropertyAccessorElement>();
+    }
     _accessors.add(element);
   }
   void addConstructor(ConstructorElement element) {
+    if (_constructors == null) {
+      _constructors = new List<ConstructorElement>();
+    }
     _constructors.add(element);
   }
   void addField(FieldElement element) {
+    if (_fields == null) {
+      _fields = new List<FieldElement>();
+    }
     _fields.add(element);
   }
   void addFunction(FunctionElement element) {
+    if (_functions == null) {
+      _functions = new List<FunctionElement>();
+    }
     _functions.add(element);
   }
   void addLabel(LabelElement element) {
+    if (_labels == null) {
+      _labels = new List<LabelElement>();
+    }
     _labels.add(element);
   }
   void addLocalVariable(LocalVariableElement element) {
+    if (_localVariables == null) {
+      _localVariables = new List<VariableElement>();
+    }
     _localVariables.add(element);
   }
   void addMethod(MethodElement element) {
+    if (_methods == null) {
+      _methods = new List<MethodElement>();
+    }
     _methods.add(element);
   }
   void addParameter(ParameterElement element) {
+    if (_parameters == null) {
+      _parameters = new List<ParameterElement>();
+    }
     _parameters.add(element);
   }
   void addTopLevelVariable(TopLevelVariableElement element) {
+    if (_topLevelVariables == null) {
+      _topLevelVariables = new List<VariableElement>();
+    }
     _topLevelVariables.add(element);
   }
   void addType(ClassElement element) {
+    if (_types == null) {
+      _types = new List<ClassElement>();
+    }
     _types.add(element);
   }
   void addTypeAlias(FunctionTypeAliasElement element) {
+    if (_typeAliases == null) {
+      _typeAliases = new List<FunctionTypeAliasElement>();
+    }
     _typeAliases.add(element);
   }
   void addTypeVariable(TypeVariableElement element) {
+    if (_typeVariables == null) {
+      _typeVariables = new List<TypeVariableElement>();
+    }
     _typeVariables.add(element);
   }
   List<PropertyAccessorElement> get accessors {
-    if (_accessors.isEmpty) {
+    if (_accessors == null) {
       return PropertyAccessorElementImpl.EMPTY_ARRAY;
     }
-    return new List.from(_accessors);
+    List<PropertyAccessorElement> result = new List.from(_accessors);
+    _accessors = null;
+    return result;
   }
   List<ConstructorElement> get constructors {
-    if (_constructors.isEmpty) {
+    if (_constructors == null) {
       return ConstructorElementImpl.EMPTY_ARRAY;
     }
-    return new List.from(_constructors);
+    List<ConstructorElement> result = new List.from(_constructors);
+    _constructors = null;
+    return result;
   }
   FieldElement getField(String fieldName) {
+    if (_fields == null) {
+      return null;
+    }
     for (FieldElement field in _fields) {
       if (field.name == fieldName) {
         return field;
@@ -737,68 +816,175 @@
     return null;
   }
   List<FieldElement> get fields {
-    if (_fields.isEmpty) {
+    if (_fields == null) {
       return FieldElementImpl.EMPTY_ARRAY;
     }
-    return new List.from(_fields);
+    List<FieldElement> result = new List.from(_fields);
+    _fields = null;
+    return result;
   }
   List<FunctionElement> get functions {
-    if (_functions.isEmpty) {
+    if (_functions == null) {
       return FunctionElementImpl.EMPTY_ARRAY;
     }
-    return new List.from(_functions);
+    List<FunctionElement> result = new List.from(_functions);
+    _functions = null;
+    return result;
   }
   List<LabelElement> get labels {
-    if (_labels.isEmpty) {
+    if (_labels == null) {
       return LabelElementImpl.EMPTY_ARRAY;
     }
-    return new List.from(_labels);
+    List<LabelElement> result = new List.from(_labels);
+    _labels = null;
+    return result;
   }
   List<LocalVariableElement> get localVariables {
-    if (_localVariables.isEmpty) {
+    if (_localVariables == null) {
       return LocalVariableElementImpl.EMPTY_ARRAY;
     }
-    return new List.from(_localVariables);
+    List<LocalVariableElement> result = new List.from(_localVariables);
+    _localVariables = null;
+    return result;
   }
   List<MethodElement> get methods {
-    if (_methods.isEmpty) {
+    if (_methods == null) {
       return MethodElementImpl.EMPTY_ARRAY;
     }
-    return new List.from(_methods);
+    List<MethodElement> result = new List.from(_methods);
+    _methods = null;
+    return result;
   }
   List<ParameterElement> get parameters {
-    if (_parameters.isEmpty) {
+    if (_parameters == null) {
       return ParameterElementImpl.EMPTY_ARRAY;
     }
-    return new List.from(_parameters);
+    List<ParameterElement> result = new List.from(_parameters);
+    _parameters = null;
+    return result;
   }
   List<TopLevelVariableElement> get topLevelVariables {
-    if (_topLevelVariables.isEmpty) {
+    if (_topLevelVariables == null) {
       return TopLevelVariableElementImpl.EMPTY_ARRAY;
     }
-    return new List.from(_topLevelVariables);
+    List<TopLevelVariableElement> result = new List.from(_topLevelVariables);
+    _topLevelVariables = null;
+    return result;
   }
   List<FunctionTypeAliasElement> get typeAliases {
-    if (_typeAliases.isEmpty) {
+    if (_typeAliases == null) {
       return FunctionTypeAliasElementImpl.EMPTY_ARRAY;
     }
-    return new List.from(_typeAliases);
+    List<FunctionTypeAliasElement> result = new List.from(_typeAliases);
+    _typeAliases = null;
+    return result;
   }
   List<ClassElement> get types {
-    if (_types.isEmpty) {
+    if (_types == null) {
       return ClassElementImpl.EMPTY_ARRAY;
     }
-    return new List.from(_types);
+    List<ClassElement> result = new List.from(_types);
+    _types = null;
+    return result;
   }
   List<TypeVariableElement> get typeVariables {
-    if (_typeVariables.isEmpty) {
+    if (_typeVariables == null) {
       return TypeVariableElementImpl.EMPTY_ARRAY;
     }
-    return new List.from(_typeVariables);
+    List<TypeVariableElement> result = new List.from(_typeVariables);
+    _typeVariables = null;
+    return result;
+  }
+  void validate() {
+    JavaStringBuilder builder = new JavaStringBuilder();
+    if (_accessors != null) {
+      builder.append(_accessors.length);
+      builder.append(" accessors");
+    }
+    if (_constructors != null) {
+      if (builder.length > 0) {
+        builder.append("; ");
+      }
+      builder.append(_constructors.length);
+      builder.append(" constructors");
+    }
+    if (_fields != null) {
+      if (builder.length > 0) {
+        builder.append("; ");
+      }
+      builder.append(_fields.length);
+      builder.append(" fields");
+    }
+    if (_functions != null) {
+      if (builder.length > 0) {
+        builder.append("; ");
+      }
+      builder.append(_functions.length);
+      builder.append(" functions");
+    }
+    if (_labels != null) {
+      if (builder.length > 0) {
+        builder.append("; ");
+      }
+      builder.append(_labels.length);
+      builder.append(" labels");
+    }
+    if (_localVariables != null) {
+      if (builder.length > 0) {
+        builder.append("; ");
+      }
+      builder.append(_localVariables.length);
+      builder.append(" local variables");
+    }
+    if (_methods != null) {
+      if (builder.length > 0) {
+        builder.append("; ");
+      }
+      builder.append(_methods.length);
+      builder.append(" methods");
+    }
+    if (_parameters != null) {
+      if (builder.length > 0) {
+        builder.append("; ");
+      }
+      builder.append(_parameters.length);
+      builder.append(" parameters");
+    }
+    if (_topLevelVariables != null) {
+      if (builder.length > 0) {
+        builder.append("; ");
+      }
+      builder.append(_topLevelVariables.length);
+      builder.append(" top-level variables");
+    }
+    if (_types != null) {
+      if (builder.length > 0) {
+        builder.append("; ");
+      }
+      builder.append(_types.length);
+      builder.append(" types");
+    }
+    if (_typeAliases != null) {
+      if (builder.length > 0) {
+        builder.append("; ");
+      }
+      builder.append(_typeAliases.length);
+      builder.append(" type aliases");
+    }
+    if (_typeVariables != null) {
+      if (builder.length > 0) {
+        builder.append("; ");
+      }
+      builder.append(_typeVariables.length);
+      builder.append(" type variables");
+    }
+    if (builder.length > 0) {
+      AnalysisEngine.instance.logger.logError("Failed to capture elements: ${builder.toString()}");
+    }
   }
 }
 /**
- * Instances of the class {@code HtmlUnitBuilder} build an element model for a single HTML unit.
+ * Instances of the class `HtmlUnitBuilder` build an element model for a single HTML unit.
  */
 class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
   static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\"";
@@ -818,7 +1004,7 @@
   RecordingErrorListener _errorListener;
 
   /**
-   * The line information associated with the source for which an element is being built, or{@code null} if we are not building an element.
+   * The line information associated with the source for which an element is being built, or`null` if we are not building an element.
    */
   LineInfo _lineInfo;
 
@@ -977,7 +1163,7 @@
   }
 
   /**
-   * Return the first source attribute for the given tag node, or {@code null} if it does not exist.
+   * Return the first source attribute for the given tag node, or `null` if it does not exist.
    * @param node the node containing attributes
    * @return the source attribute contained in the given tag
    */
@@ -992,8 +1178,8 @@
 
   /**
    * Determine if the specified node is a Dart script.
-   * @param node the node to be tested (not {@code null})
-   * @return {@code true} if the node is a Dart script
+   * @param node the node to be tested (not `null`)
+   * @return `true` if the node is a Dart script
    */
   bool isScriptNode(ht.XmlTagNode node) {
     if (node.tagNodes.length != 0 || node.tag.lexeme != _SCRIPT) {
@@ -1026,7 +1212,7 @@
   }
 }
 /**
- * Instances of the class {@code DeclarationResolver} are used to resolve declarations in an AST
+ * Instances of the class `DeclarationResolver` are used to resolve declarations in an AST
  * structure to already built elements.
  */
 class DeclarationResolver extends RecursiveASTVisitor<Object> {
@@ -1037,25 +1223,25 @@
   CompilationUnitElement _enclosingUnit;
 
   /**
-   * The function type alias containing the AST nodes being visited, or {@code null} if we are not
+   * The function type alias containing the AST nodes being visited, or `null` if we are not
    * in the scope of a function type alias.
    */
   FunctionTypeAliasElement _enclosingAlias;
 
   /**
-   * The class containing the AST nodes being visited, or {@code null} if we are not in the scope of
+   * The class containing the AST nodes being visited, or `null` if we are not in the scope of
    * a class.
    */
   ClassElement _enclosingClass;
 
   /**
-   * The method or function containing the AST nodes being visited, or {@code null} if we are not in
+   * The method or function containing the AST nodes being visited, or `null` if we are not in
    * the scope of a method or function.
    */
   ExecutableElement _enclosingExecutable;
 
   /**
-   * The parameter containing the AST nodes being visited, or {@code null} if we are not in the
+   * The parameter containing the AST nodes being visited, or `null` if we are not in the
    * scope of a parameter.
    */
   ParameterElement _enclosingParameter;
@@ -1401,7 +1587,7 @@
   }
 
   /**
-   * Return the element for the part with the given source, or {@code null} if there is no element
+   * Return the element for the part with the given source, or `null` if there is no element
    * for the given source.
    * @param parts the elements for the parts
    * @param partSource the source for the part whose element is to be returned
@@ -1456,7 +1642,7 @@
   }
 
   /**
-   * Return the export element from the given array whose library has the given source, or{@code null} if there is no such export.
+   * Return the export element from the given array whose library has the given source, or`null` if there is no such export.
    * @param exports the export elements being searched
    * @param source the source of the library associated with the export element to being searched
    * for
@@ -1473,7 +1659,7 @@
 
   /**
    * Return the import element from the given array whose library has the given source and that has
-   * the given prefix, or {@code null} if there is no such import.
+   * the given prefix, or `null` if there is no such import.
    * @param imports the import elements being searched
    * @param source the source of the library associated with the import element to being searched
    * for
@@ -1499,7 +1685,7 @@
   }
 
   /**
-   * Return the value of the given string literal, or {@code null} if the string is not a constant
+   * Return the value of the given string literal, or `null` if the string is not a constant
    * string without any string interpolation.
    * @param literal the string literal whose value is to be returned
    * @return the value of the given string literal
@@ -1518,45 +1704,45 @@
   }
 }
 /**
- * Instances of the class {@code ElementResolver} are used by instances of {@link ResolverVisitor}to resolve references within the AST structure to the elements being referenced. The requirements
+ * Instances of the class `ElementResolver` are used by instances of [ResolverVisitor]to resolve references within the AST structure to the elements being referenced. The requirements
  * for the element resolver are:
  * <ol>
- * <li>Every {@link SimpleIdentifier} should be resolved to the element to which it refers.
+ * * Every [SimpleIdentifier] should be resolved to the element to which it refers.
  * Specifically:
- * <ul>
- * <li>An identifier within the declaration of that name should resolve to the element being
- * declared.</li>
- * <li>An identifier denoting a prefix should resolve to the element representing the import that
- * defines the prefix (an {@link ImportElement}).</li>
- * <li>An identifier denoting a variable should resolve to the element representing the variable (a{@link VariableElement}).</li>
- * <li>An identifier denoting a parameter should resolve to the element representing the parameter
- * (a {@link ParameterElement}).</li>
- * <li>An identifier denoting a field should resolve to the element representing the getter or
- * setter being invoked (a {@link PropertyAccessorElement}).</li>
- * <li>An identifier denoting the name of a method or function being invoked should resolve to the
- * element representing the method or function (a {@link ExecutableElement}).</li>
- * <li>An identifier denoting a label should resolve to the element representing the label (a{@link LabelElement}).</li>
- * </ul>
- * The identifiers within directives are exceptions to this rule and are covered below.</li>
- * <li>Every node containing a token representing an operator that can be overridden ({@link BinaryExpression}, {@link PrefixExpression}, {@link PostfixExpression}) should resolve to
- * the element representing the method invoked by that operator (a {@link MethodElement}).</li>
- * <li>Every {@link FunctionExpressionInvocation} should resolve to the element representing the
- * function being invoked (a {@link FunctionElement}). This will be the same element as that to
+ *
+ * * An identifier within the declaration of that name should resolve to the element being
+ * declared.
+ * * An identifier denoting a prefix should resolve to the element representing the import that
+ * defines the prefix (an [ImportElement]).
+ * * An identifier denoting a variable should resolve to the element representing the variable (a[VariableElement]).
+ * * An identifier denoting a parameter should resolve to the element representing the parameter
+ * (a [ParameterElement]).
+ * * An identifier denoting a field should resolve to the element representing the getter or
+ * setter being invoked (a [PropertyAccessorElement]).
+ * * An identifier denoting the name of a method or function being invoked should resolve to the
+ * element representing the method or function (a [ExecutableElement]).
+ * * An identifier denoting a label should resolve to the element representing the label (a[LabelElement]).
+ *
+ * The identifiers within directives are exceptions to this rule and are covered below.
+ * * Every node containing a token representing an operator that can be overridden ([BinaryExpression], [PrefixExpression], [PostfixExpression]) should resolve to
+ * the element representing the method invoked by that operator (a [MethodElement]).
+ * * Every [FunctionExpressionInvocation] should resolve to the element representing the
+ * function being invoked (a [FunctionElement]). This will be the same element as that to
  * which the name is resolved if the function has a name, but is provided for those cases where an
- * unnamed function is being invoked.</li>
- * <li>Every {@link LibraryDirective} and {@link PartOfDirective} should resolve to the element
- * representing the library being specified by the directive (a {@link LibraryElement}) unless, in
- * the case of a part-of directive, the specified library does not exist.</li>
- * <li>Every {@link ImportDirective} and {@link ExportDirective} should resolve to the element
+ * unnamed function is being invoked.
+ * * Every [LibraryDirective] and [PartOfDirective] should resolve to the element
+ * representing the library being specified by the directive (a [LibraryElement]) unless, in
+ * the case of a part-of directive, the specified library does not exist.
+ * * Every [ImportDirective] and [ExportDirective] should resolve to the element
  * representing the library being specified by the directive unless the specified library does not
- * exist (an {@link ImportElement} or {@link ExportElement}).</li>
- * <li>The identifier representing the prefix in an {@link ImportDirective} should resolve to the
- * element representing the prefix (a {@link PrefixElement}).</li>
- * <li>The identifiers in the hide and show combinators in {@link ImportDirective}s and{@link ExportDirective}s should resolve to the elements that are being hidden or shown,
+ * exist (an [ImportElement] or [ExportElement]).
+ * * The identifier representing the prefix in an [ImportDirective] should resolve to the
+ * element representing the prefix (a [PrefixElement]).
+ * * The identifiers in the hide and show combinators in [ImportDirective]s and[ExportDirective]s should resolve to the elements that are being hidden or shown,
  * respectively, unless those names are not defined in the specified library (or the specified
- * library does not exist).</li>
- * <li>Every {@link PartDirective} should resolve to the element representing the compilation unit
- * being specified by the string unless the specified compilation unit does not exist (a{@link CompilationUnitElement}).</li>
+ * library does not exist).
+ * * Every [PartDirective] should resolve to the element representing the compilation unit
+ * being specified by the string unless the specified compilation unit does not exist (a[CompilationUnitElement]).
  * </ol>
  * Note that AST nodes that would represent elements that are not defined are not resolved to
  * anything. This includes such things as references to undeclared variables (which is an error) and
@@ -1567,7 +1753,7 @@
 class ElementResolver extends SimpleASTVisitor<Object> {
 
   /**
-   * @return {@code true} if the given identifier is the return type of a constructor declaration.
+   * @return `true` if the given identifier is the return type of a constructor declaration.
    */
   static bool isConstructorReturnType(SimpleIdentifier node) {
     ASTNode parent = node.parent;
@@ -1579,7 +1765,7 @@
   }
 
   /**
-   * @return {@code true} if the given identifier is the return type of a factory constructor
+   * @return `true` if the given identifier is the return type of a factory constructor
    * declaration.
    */
   static bool isFactoryConstructorReturnType(SimpleIdentifier node) {
@@ -1594,7 +1780,7 @@
   /**
    * Checks if the given 'super' expression is used in the valid context.
    * @param node the 'super' expression to analyze
-   * @return {@code true} if the given 'super' expression is in the valid context
+   * @return `true` if the given 'super' expression is in the valid context
    */
   static bool isSuperInValidContext(SuperExpression node) {
     for (ASTNode n = node; n != null; n = n.parent) {
@@ -1610,7 +1796,7 @@
       }
       if (n is MethodDeclaration) {
         MethodDeclaration method = n as MethodDeclaration;
-        return !method.isStatic();
+        return !method.isStatic;
       }
     }
     return false;
@@ -1660,7 +1846,7 @@
         node.staticElement = staticMethod;
         Type2 propagatedType = getPropagatedType(leftHandSide);
         MethodElement propagatedMethod = lookUpMethod(leftHandSide, propagatedType, methodName);
-        node.element = select3(staticMethod, propagatedMethod);
+        node.element = select2(staticMethod, propagatedMethod);
         if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
           _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_METHOD, operator, [methodName, staticType.displayName]);
         }
@@ -1670,7 +1856,7 @@
   }
   Object visitBinaryExpression(BinaryExpression node) {
     sc.Token operator = node.operator;
-    if (operator.isUserDefinableOperator()) {
+    if (operator.isUserDefinableOperator) {
       Expression leftOperand = node.leftOperand;
       if (leftOperand != null) {
         String methodName = operator.lexeme;
@@ -1679,7 +1865,7 @@
         node.staticElement = staticMethod;
         Type2 propagatedType = getPropagatedType(leftOperand);
         MethodElement propagatedMethod = lookUpMethod(leftOperand, propagatedType, methodName);
-        node.element = select3(staticMethod, propagatedMethod);
+        node.element = select2(staticMethod, propagatedMethod);
         if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
           _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displayName]);
         }
@@ -1690,7 +1876,7 @@
   Object visitBreakStatement(BreakStatement node) {
     SimpleIdentifier labelNode = node.label;
     LabelElementImpl labelElement = lookupLabel(node, labelNode);
-    if (labelElement != null && labelElement.isOnSwitchMember()) {
+    if (labelElement != null && labelElement.isOnSwitchMember) {
       _resolver.reportError(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode, []);
     }
     return null;
@@ -1716,7 +1902,7 @@
       }
       if (element == null) {
       } else {
-        if (element.library != _resolver.definingLibrary) {
+        if (element.library == null || element.library != _resolver.definingLibrary) {
         }
         recordResolution(simpleIdentifier, element);
         if (node.newKeyword != null) {
@@ -1803,21 +1989,21 @@
     ClassElement enclosingClass = _resolver.enclosingClass;
     FieldElement fieldElement = ((enclosingClass as ClassElementImpl)).getField(fieldName.name);
     recordResolution(fieldName, fieldElement);
-    if (fieldElement == null || fieldElement.isSynthetic()) {
+    if (fieldElement == null || fieldElement.isSynthetic) {
       _resolver.reportError(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
-    } else if (fieldElement.isStatic()) {
+    } else if (fieldElement.isStatic) {
       _resolver.reportError(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [fieldName]);
     }
     return null;
   }
   Object visitConstructorName(ConstructorName node) {
     Type2 type = node.type.type;
-    if (type != null && type.isDynamic()) {
+    if (type != null && type.isDynamic) {
       return null;
     } else if (type is! InterfaceType) {
       ASTNode parent = node.parent;
       if (parent is InstanceCreationExpression) {
-        if (((parent as InstanceCreationExpression)).isConst()) {
+        if (((parent as InstanceCreationExpression)).isConst) {
         } else {
         }
       } else {
@@ -1842,7 +2028,7 @@
   Object visitContinueStatement(ContinueStatement node) {
     SimpleIdentifier labelNode = node.label;
     LabelElementImpl labelElement = lookupLabel(node, labelNode);
-    if (labelElement != null && labelElement.isOnSwitchStatement()) {
+    if (labelElement != null && labelElement.isOnSwitchStatement) {
       _resolver.reportError(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode, []);
     }
     return null;
@@ -1876,17 +2062,17 @@
           if (node.type == null) {
             fieldFormal.type = fieldType;
           }
-          if (fieldElement.isSynthetic()) {
+          if (fieldElement.isSynthetic) {
             _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
-          } else if (fieldElement.isStatic()) {
+          } else if (fieldElement.isStatic) {
             _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]);
           } else if (declaredType != null && fieldType != null && !declaredType.isAssignableTo(fieldType)) {
             _resolver.reportError(StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName]);
           }
         } else {
-          if (fieldElement.isSynthetic()) {
+          if (fieldElement.isSynthetic) {
             _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
-          } else if (fieldElement.isStatic()) {
+          } else if (fieldElement.isStatic) {
             _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]);
           }
         }
@@ -1947,7 +2133,7 @@
     node.staticElement = invokedConstructor;
     node.element = invokedConstructor;
     ArgumentList argumentList = node.argumentList;
-    List<ParameterElement> parameters = resolveArgumentsToParameters(node.isConst(), argumentList, invokedConstructor);
+    List<ParameterElement> parameters = resolveArgumentsToParameters(node.isConst, argumentList, invokedConstructor);
     if (parameters != null) {
       argumentList.correspondingStaticParameters = parameters;
     }
@@ -1993,20 +2179,7 @@
         argumentList.correspondingParameters = parameters;
       }
     }
-    ErrorCode errorCode;
-    if (staticElement == null) {
-      if (propagatedElement == null) {
-        errorCode = checkForInvocationError(target, staticElement);
-      } else {
-        errorCode = checkForInvocationError(target, propagatedElement);
-      }
-    } else {
-      errorCode = checkForInvocationError(target, staticElement);
-      if (propagatedElement != null) {
-        ErrorCode propagatedError = checkForInvocationError(target, propagatedElement);
-        errorCode = select(errorCode, propagatedError);
-      }
-    }
+    ErrorCode errorCode = checkForInvocationError(target, staticElement);
     if (identical(errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION)) {
       _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName, [methodName.name]);
     } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) {
@@ -2050,7 +2223,7 @@
     node.staticElement = staticMethod;
     Type2 propagatedType = getPropagatedType(operand);
     MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, methodName);
-    node.element = select3(staticMethod, propagatedMethod);
+    node.element = select2(staticMethod, propagatedMethod);
     if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
       _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_OPERATOR, node.operator, [methodName, staticType.displayName]);
     }
@@ -2083,7 +2256,7 @@
   Object visitPrefixExpression(PrefixExpression node) {
     sc.Token operator = node.operator;
     sc.TokenType operatorType = operator.type;
-    if (operatorType.isUserDefinableOperator() || identical(operatorType, sc.TokenType.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) {
+    if (operatorType.isUserDefinableOperator || identical(operatorType, sc.TokenType.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) {
       Expression operand = node.operand;
       String methodName = getPrefixOperator(node);
       Type2 staticType = getStaticType(operand);
@@ -2091,7 +2264,7 @@
       node.staticElement = staticMethod;
       Type2 propagatedType = getPropagatedType(operand);
       MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, methodName);
-      node.element = select3(staticMethod, propagatedMethod);
+      node.element = select2(staticMethod, propagatedMethod);
       if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
         _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displayName]);
       }
@@ -2175,7 +2348,7 @@
       }
       return null;
     } else {
-      if (element.isFactory()) {
+      if (element.isFactory) {
         _resolver.reportError(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]);
       }
     }
@@ -2230,8 +2403,8 @@
 
   /**
    * Given that we have found code to invoke the given element, return the error code that should be
-   * reported, or {@code null} if no error should be reported.
-   * @param target the target of the invocation, or {@code null} if there was no target
+   * reported, or `null` if no error should be reported.
+   * @param target the target of the invocation, or `null` if there was no target
    * @param element the element to be invoked
    * @return the error code that should be reported
    */
@@ -2282,7 +2455,7 @@
           Type2 targetType = getStaticType(target);
           if (targetType == null) {
             return StaticTypeWarningCode.UNDEFINED_FUNCTION;
-          } else if (!targetType.isDynamic() && !classDeclaresNoSuchMethod2(targetType.element)) {
+          } else if (!targetType.isDynamic && !classDeclaresNoSuchMethod2(targetType.element)) {
             return StaticTypeWarningCode.UNDEFINED_METHOD;
           }
         }
@@ -2292,10 +2465,10 @@
   }
 
   /**
-   * Return {@code true} if the given class declares a method named "noSuchMethod" and is not the
+   * Return `true` if the given class declares a method named "noSuchMethod" and is not the
    * class 'Object'.
    * @param element the class being tested
-   * @return {@code true} if the given class declares a method named "noSuchMethod"
+   * @return `true` if the given class declares a method named "noSuchMethod"
    */
   bool classDeclaresNoSuchMethod(ClassElement classElement) {
     if (classElement == null) {
@@ -2306,10 +2479,10 @@
   }
 
   /**
-   * Return {@code true} if the given element represents a class that declares a method named
+   * Return `true` if the given element represents a class that declares a method named
    * "noSuchMethod" and is not the class 'Object'.
    * @param element the element being tested
-   * @return {@code true} if the given element represents a class that declares a method named
+   * @return `true` if the given element represents a class that declares a method named
    * "noSuchMethod"
    */
   bool classDeclaresNoSuchMethod2(Element element) {
@@ -2322,7 +2495,7 @@
   /**
    * Given a list of arguments and the element that will be invoked using those argument, compute
    * the list of parameters that correspond to the list of arguments. Return the parameters that
-   * correspond to the arguments, or {@code null} if no correspondence could be computed.
+   * correspond to the arguments, or `null` if no correspondence could be computed.
    * @param argumentList the list of arguments being passed to the element
    * @param executableElement the element that will be invoked with the arguments
    * @return the parameters that correspond to the arguments
@@ -2379,7 +2552,7 @@
 
   /**
    * Look for any declarations of the given identifier that are imported using a prefix. Return the
-   * element that was found, or {@code null} if the name is not imported using a prefix.
+   * element that was found, or `null` if the name is not imported using a prefix.
    * @param identifier the identifier that might have been imported using a prefix
    * @return the element that was found
    */
@@ -2473,13 +2646,13 @@
   }
 
   /**
-   * Return {@code true} if the given type represents an object that could be invoked using the call
+   * Return `true` if the given type represents an object that could be invoked using the call
    * operator '()'.
    * @param type the type being tested
-   * @return {@code true} if the given type represents an object that could be invoked
+   * @return `true` if the given type represents an object that could be invoked
    */
   bool isExecutableType(Type2 type) {
-    if (type.isDynamic() || (type is FunctionType) || type.isDartCoreFunction()) {
+    if (type.isDynamic || (type is FunctionType) || type.isDartCoreFunction) {
       return true;
     } else if (type is InterfaceType) {
       ClassElement classElement = ((type as InterfaceType)).element;
@@ -2490,32 +2663,32 @@
   }
 
   /**
-   * Return {@code true} if the given element is a static element.
+   * Return `true` if the given element is a static element.
    * @param element the element being tested
-   * @return {@code true} if the given element is a static element
+   * @return `true` if the given element is a static element
    */
   bool isStatic(Element element) {
     if (element is ExecutableElement) {
-      return ((element as ExecutableElement)).isStatic();
+      return ((element as ExecutableElement)).isStatic;
     } else if (element is PropertyInducingElement) {
-      return ((element as PropertyInducingElement)).isStatic();
+      return ((element as PropertyInducingElement)).isStatic;
     }
     return false;
   }
 
   /**
-   * Looks up the method element with the given name for index expression, reports{@link StaticWarningCode#UNDEFINED_OPERATOR} if not found.
+   * Looks up the method element with the given name for index expression, reports[StaticWarningCode#UNDEFINED_OPERATOR] if not found.
    * @param node the index expression to resolve
    * @param target the target of the expression
    * @param methodName the name of the operator associated with the context of using of the given
    * index expression
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    */
   bool lookUpCheckIndexOperator(IndexExpression node, Expression target, String methodName, Type2 staticType, Type2 propagatedType) {
     MethodElement staticMethod = lookUpMethod(target, staticType, methodName);
     MethodElement propagatedMethod = lookUpMethod(target, propagatedType, methodName);
     node.staticElement = staticMethod;
-    node.element = select3(staticMethod, propagatedMethod);
+    node.element = select2(staticMethod, propagatedMethod);
     if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
       sc.Token leftBracket = node.leftBracket;
       sc.Token rightBracket = node.rightBracket;
@@ -2534,8 +2707,8 @@
 
   /**
    * Look up the getter with the given name in the given type. Return the element representing the
-   * getter that was found, or {@code null} if there is no getter with the given name.
-   * @param target the target of the invocation, or {@code null} if there is no target
+   * getter that was found, or `null` if there is no getter with the given name.
+   * @param target the target of the invocation, or `null` if there is no target
    * @param type the type in which the getter is defined
    * @param getterName the name of the getter being looked up
    * @return the element representing the getter that was found
@@ -2560,9 +2733,9 @@
 
   /**
    * Look up the getter with the given name in the interfaces implemented by the given type, either
-   * directly or indirectly. Return the element representing the getter that was found, or{@code null} if there is no getter with the given name.
+   * directly or indirectly. Return the element representing the getter that was found, or`null` if there is no getter with the given name.
    * @param targetType the type in which the getter might be defined
-   * @param includeTargetType {@code true} if the search should include the target type
+   * @param includeTargetType `true` if the search should include the target type
    * @param getterName the name of the getter being looked up
    * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
    * to prevent infinite recursion and to optimize the search
@@ -2601,7 +2774,7 @@
 
   /**
    * Look up the method or getter with the given name in the given type. Return the element
-   * representing the method or getter that was found, or {@code null} if there is no method or
+   * representing the method or getter that was found, or `null` if there is no method or
    * getter with the given name.
    * @param type the type in which the method or getter is defined
    * @param memberName the name of the method or getter being looked up
@@ -2627,9 +2800,9 @@
   /**
    * Look up the method or getter with the given name in the interfaces implemented by the given
    * type, either directly or indirectly. Return the element representing the method or getter that
-   * was found, or {@code null} if there is no method or getter with the given name.
+   * was found, or `null` if there is no method or getter with the given name.
    * @param targetType the type in which the method or getter might be defined
-   * @param includeTargetType {@code true} if the search should include the target type
+   * @param includeTargetType `true` if the search should include the target type
    * @param memberName the name of the method or getter being looked up
    * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
    * to prevent infinite recursion and to optimize the search
@@ -2711,8 +2884,8 @@
 
   /**
    * Look up the method with the given name in the given type. Return the element representing the
-   * method that was found, or {@code null} if there is no method with the given name.
-   * @param target the target of the invocation, or {@code null} if there is no target
+   * method that was found, or `null` if there is no method with the given name.
+   * @param target the target of the invocation, or `null` if there is no target
    * @param type the type in which the method is defined
    * @param methodName the name of the method being looked up
    * @return the element representing the method that was found
@@ -2737,9 +2910,9 @@
 
   /**
    * Look up the method with the given name in the interfaces implemented by the given type, either
-   * directly or indirectly. Return the element representing the method that was found, or{@code null} if there is no method with the given name.
+   * directly or indirectly. Return the element representing the method that was found, or`null` if there is no method with the given name.
    * @param targetType the type in which the member might be defined
-   * @param includeTargetType {@code true} if the search should include the target type
+   * @param includeTargetType `true` if the search should include the target type
    * @param methodName the name of the method being looked up
    * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
    * to prevent infinite recursion and to optimize the search
@@ -2778,8 +2951,8 @@
 
   /**
    * Look up the setter with the given name in the given type. Return the element representing the
-   * setter that was found, or {@code null} if there is no setter with the given name.
-   * @param target the target of the invocation, or {@code null} if there is no target
+   * setter that was found, or `null` if there is no setter with the given name.
+   * @param target the target of the invocation, or `null` if there is no target
    * @param type the type in which the setter is defined
    * @param setterName the name of the setter being looked up
    * @return the element representing the setter that was found
@@ -2804,9 +2977,9 @@
 
   /**
    * Look up the setter with the given name in the interfaces implemented by the given type, either
-   * directly or indirectly. Return the element representing the setter that was found, or{@code null} if there is no setter with the given name.
+   * directly or indirectly. Return the element representing the setter that was found, or`null` if there is no setter with the given name.
    * @param targetType the type in which the setter might be defined
-   * @param includeTargetType {@code true} if the search should include the target type
+   * @param includeTargetType `true` if the search should include the target type
    * @param setterName the name of the setter being looked up
    * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
    * to prevent infinite recursion and to optimize the search
@@ -2906,8 +3079,8 @@
   /**
    * Given a list of arguments and the element that will be invoked using those argument, compute
    * the list of parameters that correspond to the list of arguments. Return the parameters that
-   * correspond to the arguments, or {@code null} if no correspondence could be computed.
-   * @param reportError if {@code true} then compile-time error should be reported; if {@code false}then compile-time warning
+   * correspond to the arguments, or `null` if no correspondence could be computed.
+   * @param reportError if `true` then compile-time error should be reported; if `false`then compile-time warning
    * @param argumentList the list of arguments being passed to the element
    * @param executableElement the element that will be invoked with the arguments
    * @return the parameters that correspond to the arguments
@@ -2924,7 +3097,7 @@
    * Given a list of arguments and the parameters related to the element that will be invoked using
    * those argument, compute the list of parameters that correspond to the list of arguments. Return
    * the parameters that correspond to the arguments.
-   * @param reportError if {@code true} then compile-time error should be reported; if {@code false}then compile-time warning
+   * @param reportError if `true` then compile-time error should be reported; if `false`then compile-time warning
    * @param argumentList the list of arguments being passed to the element
    * @param parameters the of the function that will be invoked with the arguments
    * @return the parameters that correspond to the arguments
@@ -3093,7 +3266,7 @@
     propertyName.staticElement = staticElement;
     Type2 propagatedType = getPropagatedType(target);
     ExecutableElement propagatedElement = resolveProperty(target, propagatedType, propertyName);
-    Element selectedElement = select2(staticElement, propagatedElement);
+    Element selectedElement = select(staticElement, propagatedElement);
     propertyName.element = selectedElement;
     if (shouldReportMissingMember(staticType, staticElement) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedElement))) {
       bool staticNoSuchMethod = staticType != null && classDeclaresNoSuchMethod2(staticType.element);
@@ -3121,7 +3294,7 @@
 
   /**
    * Resolve the given simple identifier if possible. Return the element to which it could be
-   * resolved, or {@code null} if it could not be resolved. This does not record the results of the
+   * resolved, or `null` if it could not be resolved. This does not record the results of the
    * resolution.
    * @param node the identifier to be resolved
    * @return the element to which the identifier could be resolved
@@ -3180,35 +3353,20 @@
   }
 
   /**
-   * Given two possible error codes for the same piece of code, one computed using static type
-   * information and the other using propagated type information, return the error code that should
-   * be reported, or {@code null} if no error should be reported.
-   * @param staticError the error code computed using static type information
-   * @param propagatedError the error code computed using propagated type information
-   * @return the error code that should be reported
-   */
-  ErrorCode select(ErrorCode staticError, ErrorCode propagatedError) {
-    if (staticError == null || propagatedError == null) {
-      return null;
-    }
-    return propagatedError;
-  }
-
-  /**
-   * Return the propagated element if it is not {@code null}, or the static element if it is.
+   * Return the propagated element if it is not `null`, or the static element if it is.
    * @param staticElement the element computed using static type information
    * @param propagatedElement the element computed using propagated type information
    * @return the more specific of the two elements
    */
-  ExecutableElement select2(ExecutableElement staticElement, ExecutableElement propagatedElement) => propagatedElement != null ? propagatedElement : staticElement;
+  ExecutableElement select(ExecutableElement staticElement, ExecutableElement propagatedElement) => propagatedElement != null ? propagatedElement : staticElement;
 
   /**
-   * Return the propagated method if it is not {@code null}, or the static method if it is.
+   * Return the propagated method if it is not `null`, or the static method if it is.
    * @param staticMethod the method computed using static type information
    * @param propagatedMethod the method computed using propagated type information
    * @return the more specific of the two methods
    */
-  MethodElement select3(MethodElement staticMethod, MethodElement propagatedMethod) => propagatedMethod != null ? propagatedMethod : staticMethod;
+  MethodElement select2(MethodElement staticMethod, MethodElement propagatedMethod) => propagatedMethod != null ? propagatedMethod : staticMethod;
 
   /**
    * Given a node that can have annotations associated with it and the element to which that node
@@ -3240,14 +3398,14 @@
   }
 
   /**
-   * Return {@code true} if we should report an error as a result of looking up a member in the
+   * Return `true` if we should report an error as a result of looking up a member in the
    * given type and not finding any member.
    * @param type the type in which we attempted to perform the look-up
    * @param member the result of the look-up
-   * @return {@code true} if we should report an error
+   * @return `true` if we should report an error
    */
   bool shouldReportMissingMember(Type2 type, ExecutableElement member) {
-    if (member != null || type == null || type.isDynamic()) {
+    if (member != null || type == null || type.isDynamic) {
       return false;
     }
     if (type is InterfaceType) {
@@ -3257,7 +3415,7 @@
   }
 }
 /**
- * Instances of the class {@code SyntheticIdentifier} implement an identifier that can be used to
+ * Instances of the class `SyntheticIdentifier` implement an identifier that can be used to
  * look up names in the lexical scope when there is no identifier in the AST structure. There is
  * no identifier in the AST when the parser could not distinguish between a method invocation and
  * an invocation of a top-level function imported with a prefix.
@@ -3286,31 +3444,31 @@
   }
 }
 /**
- * Instances of the class {@code InheritanceManager} manage the knowledge of where class members
+ * Instances of the class `InheritanceManager` manage the knowledge of where class members
  * (methods, getters & setters) are inherited from.
  * @coverage dart.engine.resolver
  */
 class InheritanceManager {
 
   /**
-   * The {@link LibraryElement} that is managed by this manager.
+   * The [LibraryElement] that is managed by this manager.
    */
   LibraryElement _library;
 
   /**
-   * This is a mapping between each {@link ClassElement} and a map between the {@link String} member
-   * names and the associated {@link ExecutableElement} in the mixin and superclass chain.
+   * This is a mapping between each [ClassElement] and a map between the [String] member
+   * names and the associated [ExecutableElement] in the mixin and superclass chain.
    */
   Map<ClassElement, Map<String, ExecutableElement>> _classLookup;
 
   /**
-   * This is a mapping between each {@link ClassElement} and a map between the {@link String} member
-   * names and the associated {@link ExecutableElement} in the interface set.
+   * This is a mapping between each [ClassElement] and a map between the [String] member
+   * names and the associated [ExecutableElement] in the interface set.
    */
   Map<ClassElement, Map<String, ExecutableElement>> _interfaceLookup;
 
   /**
-   * A map between each visited {@link ClassElement} and the set of {@link AnalysisError}s found on
+   * A map between each visited [ClassElement] and the set of [AnalysisError]s found on
    * the class element.
    */
   Map<ClassElement, Set<AnalysisError>> _errorsInClassElement = new Map<ClassElement, Set<AnalysisError>>();
@@ -3326,35 +3484,35 @@
   }
 
   /**
-   * Return the set of {@link AnalysisError}s found on the passed {@link ClassElement}, or{@code null} if there are none.
+   * Return the set of [AnalysisError]s found on the passed [ClassElement], or`null` if there are none.
    * @param classElt the class element to query
-   * @return the set of {@link AnalysisError}s found on the passed {@link ClassElement}, or{@code null} if there are none
+   * @return the set of [AnalysisError]s found on the passed [ClassElement], or`null` if there are none
    */
   Set<AnalysisError> getErrors(ClassElement classElt) => _errorsInClassElement[classElt];
 
   /**
    * Get and return a mapping between the set of all string names of the members inherited from the
-   * passed {@link ClassElement} superclass hierarchy, and the associated {@link ExecutableElement}.
+   * passed [ClassElement] superclass hierarchy, and the associated [ExecutableElement].
    * @param classElt the class element to query
-   * @return a mapping between the set of all members inherited from the passed {@link ClassElement}superclass hierarchy, and the associated {@link ExecutableElement}
+   * @return a mapping between the set of all members inherited from the passed [ClassElement]superclass hierarchy, and the associated [ExecutableElement]
    */
   Map<String, ExecutableElement> getMapOfMembersInheritedFromClasses(ClassElement classElt) => computeClassChainLookupMap(classElt, new Set<ClassElement>());
 
   /**
    * Get and return a mapping between the set of all string names of the members inherited from the
-   * passed {@link ClassElement} interface hierarchy, and the associated {@link ExecutableElement}.
+   * passed [ClassElement] interface hierarchy, and the associated [ExecutableElement].
    * @param classElt the class element to query
-   * @return a mapping between the set of all string names of the members inherited from the passed{@link ClassElement} interface hierarchy, and the associated {@link ExecutableElement}.
+   * @return a mapping between the set of all string names of the members inherited from the passed[ClassElement] interface hierarchy, and the associated [ExecutableElement].
    */
   Map<String, ExecutableElement> getMapOfMembersInheritedFromInterfaces(ClassElement classElt) => computeInterfaceLookupMap(classElt, new Set<ClassElement>());
 
   /**
-   * Given some {@link ClassElement class element} and some member name, this returns the{@link ExecutableElement executable element} that the class inherits from the mixins,
-   * superclasses or interfaces, that has the member name, if no member is inherited {@code null} is
+   * Given some [ClassElement class element] and some member name, this returns the[ExecutableElement executable element] that the class inherits from the mixins,
+   * superclasses or interfaces, that has the member name, if no member is inherited `null` is
    * returned.
    * @param classElt the class element to query
    * @param memberName the name of the executable element to find and return
-   * @return the inherited executable element with the member name, or {@code null} if no such
+   * @return the inherited executable element with the member name, or `null` if no such
    * member exists
    */
   ExecutableElement lookupInheritance(ClassElement classElt, String memberName) {
@@ -3369,11 +3527,11 @@
   }
 
   /**
-   * Given some {@link ClassElement class element} and some member name, this returns the{@link ExecutableElement executable element} that the class either declares itself, or
-   * inherits, that has the member name, if no member is inherited {@code null} is returned.
+   * Given some [ClassElement class element] and some member name, this returns the[ExecutableElement executable element] that the class either declares itself, or
+   * inherits, that has the member name, if no member is inherited `null` is returned.
    * @param classElt the class element to query
    * @param memberName the name of the executable element to find and return
-   * @return the inherited executable element with the member name, or {@code null} if no such
+   * @return the inherited executable element with the member name, or `null` if no such
    * member exists
    */
   ExecutableElement lookupMember(ClassElement classElt, String memberName) {
@@ -3393,7 +3551,7 @@
   }
 
   /**
-   * This method takes some inherited {@link FunctionType}, and resolves all the parameterized types
+   * This method takes some inherited [FunctionType], and resolves all the parameterized types
    * in the function type, dependent on the class in which it is being overridden.
    * @param baseFunctionType the function type that is being overridden
    * @param memberName the name of the member, this is used to lookup the inheritance path of the
@@ -3413,9 +3571,9 @@
     FunctionType functionTypeToReturn = baseFunctionType;
     InterfaceType lastType = inheritancePath.removeLast();
     while (inheritancePath.length > 0) {
-      List<Type2> paramTypes = TypeVariableTypeImpl.getTypes(lastType.element.typeVariables);
-      List<Type2> argTypes = lastType.typeArguments;
-      functionTypeToReturn = functionTypeToReturn.substitute2(argTypes, paramTypes);
+      List<Type2> parameterTypes = lastType.element.type.typeArguments;
+      List<Type2> argumentTypes = lastType.typeArguments;
+      functionTypeToReturn = functionTypeToReturn.substitute2(argumentTypes, parameterTypes);
       lastType = inheritancePath.removeLast();
     }
     return functionTypeToReturn;
@@ -3423,11 +3581,11 @@
 
   /**
    * Compute and return a mapping between the set of all string names of the members inherited from
-   * the passed {@link ClassElement} superclass hierarchy, and the associated{@link ExecutableElement}.
+   * the passed [ClassElement] superclass hierarchy, and the associated[ExecutableElement].
    * @param classElt the class element to query
    * @param visitedClasses a set of visited classes passed back into this method when it calls
    * itself recursively
-   * @return a mapping between the set of all string names of the members inherited from the passed{@link ClassElement} superclass hierarchy, and the associated {@link ExecutableElement}
+   * @return a mapping between the set of all string names of the members inherited from the passed[ClassElement] superclass hierarchy, and the associated [ExecutableElement]
    */
   Map<String, ExecutableElement> computeClassChainLookupMap(ClassElement classElt, Set<ClassElement> visitedClasses) {
     Map<String, ExecutableElement> resultMap = _classLookup[classElt];
@@ -3469,7 +3627,7 @@
    * Compute and return the inheritance path given the context of a type and a member that is
    * overridden in the inheritance path (for which the type is in the path).
    * @param chain the inheritance path that is built up as this method calls itself recursively,
-   * when this method is called an empty {@link LinkedList} should be provided
+   * when this method is called an empty [LinkedList] should be provided
    * @param currentType the current type in the inheritance path
    * @param memberName the name of the member that is being looked up the inheritance path
    */
@@ -3513,11 +3671,11 @@
 
   /**
    * Compute and return a mapping between the set of all string names of the members inherited from
-   * the passed {@link ClassElement} interface hierarchy, and the associated{@link ExecutableElement}.
+   * the passed [ClassElement] interface hierarchy, and the associated[ExecutableElement].
    * @param classElt the class element to query
    * @param visitedInterfaces a set of visited classes passed back into this method when it calls
    * itself recursively
-   * @return a mapping between the set of all string names of the members inherited from the passed{@link ClassElement} interface hierarchy, and the associated {@link ExecutableElement}
+   * @return a mapping between the set of all string names of the members inherited from the passed[ClassElement] interface hierarchy, and the associated [ExecutableElement]
    */
   Map<String, ExecutableElement> computeInterfaceLookupMap(ClassElement classElt, Set<ClassElement> visitedInterfaces) {
     Map<String, ExecutableElement> resultMap = _interfaceLookup[classElt];
@@ -3529,7 +3687,7 @@
     InterfaceType supertype = classElt.supertype;
     ClassElement superclassElement = supertype != null ? supertype.element : null;
     List<InterfaceType> interfaces = classElt.interfaces;
-    if (superclassElement == null || interfaces.length == 0) {
+    if ((superclassElement == null || supertype.isObject) && interfaces.length == 0) {
       _interfaceLookup[classElt] = resultMap;
       return resultMap;
     }
@@ -3593,7 +3751,7 @@
     if (superclassElement != null) {
       List<MethodElement> methods = superclassElement.methods;
       for (MethodElement method in methods) {
-        if (method.isAccessibleIn(_library) && !method.isStatic()) {
+        if (method.isAccessibleIn(_library) && !method.isStatic) {
           String key = method.name;
           if (!unionMap.containsKey(key)) {
             Set<ExecutableElement> set = new Set<ExecutableElement>();
@@ -3606,7 +3764,7 @@
       }
       List<PropertyAccessorElement> accessors = superclassElement.accessors;
       for (PropertyAccessorElement accessor in accessors) {
-        if (accessor.isAccessibleIn(_library) && !accessor.isStatic()) {
+        if (accessor.isAccessibleIn(_library) && !accessor.isStatic) {
           String key = accessor.name;
           if (!unionMap.containsKey(key)) {
             Set<ExecutableElement> set = new Set<ExecutableElement>();
@@ -3623,7 +3781,7 @@
       if (interfaceElement != null) {
         List<MethodElement> methods = interfaceElement.methods;
         for (MethodElement method in methods) {
-          if (method.isAccessibleIn(_library) && !method.isStatic()) {
+          if (method.isAccessibleIn(_library) && !method.isStatic) {
             String key = method.name;
             if (!unionMap.containsKey(key)) {
               Set<ExecutableElement> set = new Set<ExecutableElement>();
@@ -3636,7 +3794,7 @@
         }
         List<PropertyAccessorElement> accessors = interfaceElement.accessors;
         for (PropertyAccessorElement accessor in accessors) {
-          if (accessor.isAccessibleIn(_library) && !accessor.isStatic()) {
+          if (accessor.isAccessibleIn(_library) && !accessor.isStatic) {
             String key = accessor.name;
             if (!unionMap.containsKey(key)) {
               Set<ExecutableElement> set = new Set<ExecutableElement>();
@@ -3662,7 +3820,7 @@
         for (ExecutableElement executableElement in set) {
           if (executableElement is PropertyAccessorElement) {
             allMethods = false;
-            if (((executableElement as PropertyAccessorElement)).isSetter()) {
+            if (((executableElement as PropertyAccessorElement)).isSetter) {
               allGetters = false;
             } else {
               allSetters = false;
@@ -3715,23 +3873,23 @@
   }
 
   /**
-   * Given some {@link ClassElement}, this method finds and returns the {@link ExecutableElement} of
+   * Given some [ClassElement], this method finds and returns the [ExecutableElement] of
    * the passed name in the class element. Static members, members in super types and members not
    * accessible from the current library are not considered.
    * @param classElt the class element to query
    * @param memberName the name of the member to lookup in the class
-   * @return the found {@link ExecutableElement}, or {@code null} if no such member was found
+   * @return the found [ExecutableElement], or `null` if no such member was found
    */
   ExecutableElement lookupMemberInClass(ClassElement classElt, String memberName) {
     List<MethodElement> methods = classElt.methods;
     for (MethodElement method in methods) {
-      if (memberName == method.name && method.isAccessibleIn(_library) && !method.isStatic()) {
+      if (memberName == method.name && method.isAccessibleIn(_library) && !method.isStatic) {
         return method;
       }
     }
     List<PropertyAccessorElement> accessors = classElt.accessors;
     for (PropertyAccessorElement accessor in accessors) {
-      if (memberName == accessor.name && accessor.isAccessibleIn(_library) && !accessor.isStatic()) {
+      if (memberName == accessor.name && accessor.isAccessibleIn(_library) && !accessor.isStatic) {
         return accessor;
       }
     }
@@ -3741,19 +3899,19 @@
   /**
    * Record the passed map with the set of all members (methods, getters and setters) in the class
    * into the passed map.
-   * @param map some non-{@code null}
+   * @param map some non-`null`
    * @param classElt the class element that will be recorded into the passed map
    */
   void recordMapWithClassMembers(Map<String, ExecutableElement> map, ClassElement classElt) {
     List<MethodElement> methods = classElt.methods;
     for (MethodElement method in methods) {
-      if (method.isAccessibleIn(_library) && !method.isStatic()) {
+      if (method.isAccessibleIn(_library) && !method.isStatic) {
         map[method.name] = method;
       }
     }
     List<PropertyAccessorElement> accessors = classElt.accessors;
     for (PropertyAccessorElement accessor in accessors) {
-      if (accessor.isAccessibleIn(_library) && !accessor.isStatic()) {
+      if (accessor.isAccessibleIn(_library) && !accessor.isStatic) {
         map[accessor.name] = accessor;
       }
     }
@@ -3761,7 +3919,7 @@
 
   /**
    * This method is used to report errors on when they are found computing inheritance information.
-   * See {@link ErrorVerifier#checkForInconsistentMethodInheritance()} to see where these generated
+   * See [ErrorVerifier#checkForInconsistentMethodInheritance] to see where these generated
    * error codes are reported back into the analysis engine.
    * @param classElt the location of the source for which the exception occurred
    * @param offset the offset of the location of the error
@@ -3779,7 +3937,7 @@
   }
 }
 /**
- * Instances of the class {@code Library} represent the data about a single library during the
+ * Instances of the class `Library` represent the data about a single library during the
  * resolution of some (possibly different) library. They are not intended to be used except during
  * the resolution process.
  * @coverage dart.engine.resolver
@@ -3902,8 +4060,8 @@
   CompilationUnit get definingCompilationUnit => getAST(librarySource);
 
   /**
-   * Return {@code true} if this library explicitly imports core.
-   * @return {@code true} if this library explicitly imports core
+   * Return `true` if this library explicitly imports core.
+   * @return `true` if this library explicitly imports core
    */
   bool get explicitlyImportsCore => _explicitlyImportsCore;
 
@@ -3998,7 +4156,7 @@
 
   /**
    * Return the result of resolving the URI of the given URI-based directive against the URI of the
-   * library, or {@code null} if the URI is not valid. If the URI is not valid, report the error.
+   * library, or `null` if the URI is not valid. If the URI is not valid, report the error.
    * @param directive the directive which URI should be resolved
    * @return the result of resolving the URI against the URI of the library
    */
@@ -4039,7 +4197,7 @@
 
   /**
    * Set whether this library explicitly imports core to match the given value.
-   * @param explicitlyImportsCore {@code true} if this library explicitly imports core
+   * @param explicitlyImportsCore `true` if this library explicitly imports core
    */
   void set explicitlyImportsCore(bool explicitlyImportsCore2) {
     this._explicitlyImportsCore = explicitlyImportsCore2;
@@ -4058,7 +4216,7 @@
   String toString() => _librarySource.shortName;
 
   /**
-   * Return the result of resolving the given URI against the URI of the library, or {@code null} if
+   * Return the result of resolving the given URI against the URI of the library, or `null` if
    * the URI is not valid.
    * @param uri the URI to be resolved
    * @return the result of resolving the given URI against the URI of the library
@@ -4071,7 +4229,7 @@
   }
 }
 /**
- * Instances of the class {@code LibraryElementBuilder} build an element model for a single library.
+ * Instances of the class `LibraryElementBuilder` build an element model for a single library.
  * @coverage dart.engine.resolver
  */
 class LibraryElementBuilder {
@@ -4175,12 +4333,12 @@
    */
   void collectAccessors(Map<String, PropertyAccessorElement> getters, List<PropertyAccessorElement> setters, CompilationUnitElement unit) {
     for (PropertyAccessorElement accessor in unit.accessors) {
-      if (accessor.isGetter()) {
-        if (!accessor.isSynthetic() && accessor.correspondingSetter == null) {
+      if (accessor.isGetter) {
+        if (!accessor.isSynthetic && accessor.correspondingSetter == null) {
           getters[accessor.displayName] = accessor;
         }
       } else {
-        if (!accessor.isSynthetic() && accessor.correspondingGetter == null) {
+        if (!accessor.isSynthetic && accessor.correspondingGetter == null) {
           setters.add(accessor);
         }
       }
@@ -4190,7 +4348,7 @@
   /**
    * Search the top-level functions defined in the given compilation unit for the entry point.
    * @param element the compilation unit to be searched
-   * @return the entry point that was found, or {@code null} if the compilation unit does not define
+   * @return the entry point that was found, or `null` if the compilation unit does not define
    * an entry point
    */
   FunctionElement findEntryPoint(CompilationUnitElementImpl element) {
@@ -4203,7 +4361,7 @@
   }
 
   /**
-   * Return the name of the library that the given part is declared to be a part of, or {@code null}if the part does not contain a part-of directive.
+   * Return the name of the library that the given part is declared to be a part of, or `null`if the part does not contain a part-of directive.
    * @param library the library containing the part
    * @param partSource the source representing the part
    * @param directivesToResolve a list of directives that should be resolved to the library being
@@ -4251,7 +4409,7 @@
   }
 }
 /**
- * Instances of the class {@code LibraryResolver} are used to resolve one or more mutually dependent
+ * Instances of the class `LibraryResolver` are used to resolve one or more mutually dependent
  * libraries within a single context.
  * @coverage dart.engine.resolver
  */
@@ -4264,7 +4422,7 @@
 
   /**
    * The listener to which analysis errors will be reported, this error listener is either
-   * references {@link #recordingErrorListener}, or it unions the passed{@link AnalysisErrorListener} with the {@link #recordingErrorListener}.
+   * references [recordingErrorListener], or it unions the passed[AnalysisErrorListener] with the [recordingErrorListener].
    */
   RecordingErrorListener _errorListener;
 
@@ -4327,7 +4485,7 @@
    * @param librarySource the source specifying the defining compilation unit of the library to be
    * resolved
    * @param unit the compilation unit representing the embedded library
-   * @param fullAnalysis {@code true} if a full analysis should be performed
+   * @param fullAnalysis `true` if a full analysis should be performed
    * @return the element representing the resolved library
    * @throws AnalysisException if the library could not be resolved for some reason
    */
@@ -4371,13 +4529,13 @@
 
   /**
    * Resolve the library specified by the given source in the given context.
-   * <p>
+   *
    * Note that because Dart allows circular imports between libraries, it is possible that more than
    * one library will need to be resolved. In such cases the error listener can receive errors from
    * multiple libraries.
    * @param librarySource the source specifying the defining compilation unit of the library to be
    * resolved
-   * @param fullAnalysis {@code true} if a full analysis should be performed
+   * @param fullAnalysis `true` if a full analysis should be performed
    * @return the element representing the resolved library
    * @throws AnalysisException if the library could not be resolved for some reason
    */
@@ -4500,7 +4658,7 @@
   }
 
   /**
-   * Every library now has a corresponding {@link LibraryElement}, so it is now possible to resolve
+   * Every library now has a corresponding [LibraryElement], so it is now possible to resolve
    * the import and export directives.
    * @throws AnalysisException if the defining compilation unit for any of the libraries could not
    * be accessed
@@ -4594,7 +4752,7 @@
    * Compute a dependency map of libraries reachable from the given library. A dependency map is a
    * table that maps individual libraries to a list of the libraries that either import or export
    * those libraries.
-   * <p>
+   *
    * This map is used to compute all of the libraries involved in a cycle that include the root
    * library. Given that we only add libraries that are reachable from the root library, when we
    * work backward we are guaranteed to only get libraries in the cycle.
@@ -4622,7 +4780,7 @@
 
   /**
    * Recursively traverse the libraries reachable from the given library, creating instances of the
-   * class {@link Library} to represent them, and record the references in the library objects.
+   * class [Library] to represent them, and record the references in the library objects.
    * @param library the library to be processed to find libraries that have not yet been traversed
    * @throws AnalysisException if some portion of the library graph could not be traversed
    */
@@ -4715,7 +4873,7 @@
 
   /**
    * Create an object to represent the information about the library defined by the compilation unit
-   * with the given source. Return the library object that was created, or {@code null} if the
+   * with the given source. Return the library object that was created, or `null` if the
    * source is not valid.
    * @param librarySource the source of the library's defining compilation unit
    * @return the library object that was created
@@ -4735,9 +4893,9 @@
   }
 
   /**
-   * Return {@code true} if and only if the passed {@link CompilationUnit} has a part-of directive.
-   * @param node the {@link CompilationUnit} to test
-   * @return {@code true} if and only if the passed {@link CompilationUnit} has a part-of directive
+   * Return `true` if and only if the passed [CompilationUnit] has a part-of directive.
+   * @param node the [CompilationUnit] to test
+   * @return `true` if and only if the passed [CompilationUnit] has a part-of directive
    */
   bool doesCompilationUnitHavePartOfDirective(CompilationUnit node) {
     NodeList<Directive> directives = node.directives;
@@ -4808,7 +4966,7 @@
   }
 
   /**
-   * Run additional analyses, such as the {@link ConstantVerifier} and {@link ErrorVerifier}analysis in the current cycle.
+   * Run additional analyses, such as the [ConstantVerifier] and [ErrorVerifier]analysis in the current cycle.
    * @throws AnalysisException if any of the identifiers could not be resolved or if the types in
    * the library cannot be analyzed
    */
@@ -4819,7 +4977,7 @@
   }
 
   /**
-   * Run additional analyses, such as the {@link ConstantVerifier} and {@link ErrorVerifier}analysis in the given library.
+   * Run additional analyses, such as the [ConstantVerifier] and [ErrorVerifier]analysis in the given library.
    * @param library the library to have the extra analyses processes run
    * @throws AnalysisException if any of the identifiers could not be resolved or if the types in
    * the library cannot be analyzed
@@ -4828,16 +4986,15 @@
     for (Source source in library.compilationUnitSources) {
       ErrorReporter errorReporter = new ErrorReporter(_errorListener, source);
       CompilationUnit unit = library.getAST(source);
-      ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, library.libraryElement, _typeProvider, library.inheritanceManager);
-      unit.accept(errorVerifier);
-      unit.accept(new PubVerifier(_analysisContext, errorReporter));
       ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, _typeProvider);
       unit.accept(constantVerifier);
+      ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, library.libraryElement, _typeProvider, library.inheritanceManager);
+      unit.accept(errorVerifier);
     }
   }
 }
 /**
- * Instances of the class {@code ResolverVisitor} are used to resolve the nodes within a single
+ * Instances of the class `ResolverVisitor` are used to resolve the nodes within a single
  * compilation unit.
  * @coverage dart.engine.resolver
  */
@@ -4854,13 +5011,13 @@
   StaticTypeAnalyzer _typeAnalyzer;
 
   /**
-   * The class element representing the class containing the current node, or {@code null} if the
+   * The class element representing the class containing the current node, or `null` if the
    * current node is not contained in a class.
    */
   ClassElement _enclosingClass = null;
 
   /**
-   * The element representing the function containing the current node, or {@code null} if the
+   * The element representing the function containing the current node, or `null` if the
    * current node is not contained in a function.
    */
   ExecutableElement _enclosingFunction = null;
@@ -4877,9 +5034,9 @@
    * @param typeProvider the object used to access the types from the core library
    */
   ResolverVisitor.con1(Library library, Source source, TypeProvider typeProvider) : super.con1(library, source, typeProvider) {
-    _jtd_constructor_273_impl(library, source, typeProvider);
+    _jtd_constructor_274_impl(library, source, typeProvider);
   }
-  _jtd_constructor_273_impl(Library library, Source source, TypeProvider typeProvider) {
+  _jtd_constructor_274_impl(Library library, Source source, TypeProvider typeProvider) {
     this._elementResolver = new ElementResolver(this);
     this._typeAnalyzer = new StaticTypeAnalyzer(this);
   }
@@ -4894,9 +5051,9 @@
    * during resolution
    */
   ResolverVisitor.con2(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) : super.con2(definingLibrary, source, typeProvider, errorListener) {
-    _jtd_constructor_274_impl(definingLibrary, source, typeProvider, errorListener);
+    _jtd_constructor_275_impl(definingLibrary, source, typeProvider, errorListener);
   }
-  _jtd_constructor_274_impl(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) {
+  _jtd_constructor_275_impl(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) {
     this._elementResolver = new ElementResolver(this);
     this._typeAnalyzer = new StaticTypeAnalyzer(this);
   }
@@ -5275,21 +5432,21 @@
   }
 
   /**
-   * Return the class element representing the class containing the current node, or {@code null} if
+   * Return the class element representing the class containing the current node, or `null` if
    * the current node is not contained in a class.
    * @return the class element representing the class containing the current node
    */
   ClassElement get enclosingClass => _enclosingClass;
 
   /**
-   * Return the element representing the function containing the current node, or {@code null} if
+   * Return the element representing the function containing the current node, or `null` if
    * the current node is not contained in a function.
    * @return the element representing the function containing the current node
    */
   ExecutableElement get enclosingFunction => _enclosingFunction;
 
   /**
-   * Return the element associated with the given expression whose type can be overridden, or{@code null} if there is no element whose type can be overridden.
+   * Return the element associated with the given expression whose type can be overridden, or`null` if there is no element whose type can be overridden.
    * @param expression the expression with which the element is associated
    * @return the element associated with the given expression
    */
@@ -5321,7 +5478,7 @@
     }
     if (element is PropertyInducingElement) {
       PropertyInducingElement variable = element as PropertyInducingElement;
-      if (!variable.isConst() && !variable.isFinal()) {
+      if (!variable.isConst && !variable.isFinal) {
         return;
       }
     }
@@ -5388,7 +5545,7 @@
   /**
    * The given expression is the expression used to compute the iterator for a for-each statement.
    * Attempt to compute the type of objects that will be assigned to the loop variable and return
-   * that type. Return {@code null} if the type could not be determined.
+   * that type. Return `null` if the type could not be determined.
    * @param iterator the iterator for a for-each statement
    * @return the type of objects that will be assigned to the loop variable
    */
@@ -5412,10 +5569,10 @@
   }
 
   /**
-   * Return {@code true} if the given expression terminates abruptly (that is, if any expression
+   * Return `true` if the given expression terminates abruptly (that is, if any expression
    * following the given expression will not be reached).
    * @param expression the expression being tested
-   * @return {@code true} if the given expression terminates abruptly
+   * @return `true` if the given expression terminates abruptly
    */
   bool isAbruptTermination(Expression expression2) {
     while (expression2 is ParenthesizedExpression) {
@@ -5425,10 +5582,10 @@
   }
 
   /**
-   * Return {@code true} if the given statement terminates abruptly (that is, if any statement
+   * Return `true` if the given statement terminates abruptly (that is, if any statement
    * following the given statement will not be reached).
    * @param statement the statement being tested
-   * @return {@code true} if the given statement terminates abruptly
+   * @return `true` if the given statement terminates abruptly
    */
   bool isAbruptTermination2(Statement statement) {
     if (statement is ReturnStatement || statement is BreakStatement || statement is ContinueStatement) {
@@ -5525,7 +5682,7 @@
   set enclosingClass_J2DAccessor(__v) => _enclosingClass = __v;
 }
 /**
- * The abstract class {@code ScopedVisitor} maintains name and label scopes as an AST structure is
+ * The abstract class `ScopedVisitor` maintains name and label scopes as an AST structure is
  * being visited.
  * @coverage dart.engine.resolver
  */
@@ -5557,7 +5714,7 @@
   TypeProvider _typeProvider;
 
   /**
-   * The scope used to resolve labels for {@code break} and {@code continue} statements, or{@code null} if no labels have been defined in the current context.
+   * The scope used to resolve labels for `break` and `continue` statements, or`null` if no labels have been defined in the current context.
    */
   LabelScope _labelScope;
 
@@ -5568,9 +5725,9 @@
    * @param typeProvider the object used to access the types from the core library
    */
   ScopedVisitor.con1(Library library, Source source2, TypeProvider typeProvider2) {
-    _jtd_constructor_275_impl(library, source2, typeProvider2);
+    _jtd_constructor_276_impl(library, source2, typeProvider2);
   }
-  _jtd_constructor_275_impl(Library library, Source source2, TypeProvider typeProvider2) {
+  _jtd_constructor_276_impl(Library library, Source source2, TypeProvider typeProvider2) {
     this._definingLibrary = library.libraryElement;
     this._source = source2;
     LibraryScope libraryScope = library.libraryScope;
@@ -5589,9 +5746,9 @@
    * during resolution
    */
   ScopedVisitor.con2(LibraryElement definingLibrary2, Source source2, TypeProvider typeProvider2, AnalysisErrorListener errorListener2) {
-    _jtd_constructor_276_impl(definingLibrary2, source2, typeProvider2, errorListener2);
+    _jtd_constructor_277_impl(definingLibrary2, source2, typeProvider2, errorListener2);
   }
-  _jtd_constructor_276_impl(LibraryElement definingLibrary2, Source source2, TypeProvider typeProvider2, AnalysisErrorListener errorListener2) {
+  _jtd_constructor_277_impl(LibraryElement definingLibrary2, Source source2, TypeProvider typeProvider2, AnalysisErrorListener errorListener2) {
     this._definingLibrary = definingLibrary2;
     this._source = source2;
     this._errorListener = errorListener2;
@@ -5924,12 +6081,12 @@
   }
 }
 /**
- * Instances of the class {@code StaticTypeAnalyzer} perform two type-related tasks. First, they
+ * Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
  * compute the static type of every expression. Second, they look for any static type errors or
  * warnings that might need to be generated. The requirements for the type analyzer are:
  * <ol>
- * <li>Every element that refers to types should be fully populated.
- * <li>Every node representing an expression should be resolved to the Type of the expression.</li>
+ * * Every element that refers to types should be fully populated.
+ * * Every node representing an expression should be resolved to the Type of the expression.
  * </ol>
  * @coverage dart.engine.resolver
  */
@@ -6019,7 +6176,7 @@
   Type2 _dynamicType;
 
   /**
-   * The type representing the class containing the nodes being analyzed, or {@code null} if the
+   * The type representing the class containing the nodes being analyzed, or `null` if the
    * nodes are not within a class.
    */
   InterfaceType _thisType;
@@ -6055,7 +6212,7 @@
   }
 
   /**
-   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is{@code String}.</blockquote>
+   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is`String`.</blockquote>
    */
   Object visitAdjacentStrings(AdjacentStrings node) {
     recordStaticType(node, _typeProvider.stringType);
@@ -6064,7 +6221,7 @@
 
   /**
    * The Dart Language Specification, 12.33: <blockquote>The static type of an argument definition
-   * test is {@code bool}.</blockquote>
+   * test is `bool`.</blockquote>
    */
   Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) {
     recordStaticType(node, _typeProvider.boolType);
@@ -6073,10 +6230,10 @@
 
   /**
    * The Dart Language Specification, 12.32: <blockquote>... the cast expression <i>e as T</i> ...
-   * <p>
+   *
    * It is a static warning if <i>T</i> does not denote a type available in the current lexical
    * scope.
-   * <p>
+   *
    * The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote>
    */
   Object visitAsExpression(AsExpression node) {
@@ -6087,33 +6244,33 @@
   /**
    * The Dart Language Specification, 12.18: <blockquote>... an assignment <i>a</i> of the form <i>v
    * = e</i> ...
-   * <p>
+   *
    * It is a static type warning if the static type of <i>e</i> may not be assigned to the static
    * type of <i>v</i>.
-   * <p>
+   *
    * The static type of the expression <i>v = e</i> is the static type of <i>e</i>.
-   * <p>
+   *
    * ... an assignment of the form <i>C.v = e</i> ...
-   * <p>
+   *
    * It is a static type warning if the static type of <i>e</i> may not be assigned to the static
    * type of <i>C.v</i>.
-   * <p>
+   *
    * The static type of the expression <i>C.v = e</i> is the static type of <i>e</i>.
-   * <p>
+   *
    * ... an assignment of the form <i>e<sub>1</sub>.v = e<sub>2</sub></i> ...
-   * <p>
+   *
    * Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static type warning if
    * <i>T</i> does not have an accessible instance setter named <i>v=</i>. It is a static type
    * warning if the static type of <i>e<sub>2</sub></i> may not be assigned to <i>T</i>.
-   * <p>
+   *
    * The static type of the expression <i>e<sub>1</sub>.v = e<sub>2</sub></i> is the static type of
    * <i>e<sub>2</sub></i>.
-   * <p>
+   *
    * ... an assignment of the form <i>e<sub>1</sub>\[e<sub>2</sub>\] = e<sub>3</sub></i> ...
-   * <p>
+   *
    * The static type of the expression <i>e<sub>1</sub>\[e<sub>2</sub>\] = e<sub>3</sub></i> is the
    * static type of <i>e<sub>3</sub></i>.
-   * <p>
+   *
    * A compound assignment of the form <i>v op= e</i> is equivalent to <i>v = v op e</i>. A compound
    * assignment of the form <i>C.v op= e</i> is equivalent to <i>C.v = C.v op e</i>. A compound
    * assignment of the form <i>e<sub>1</sub>.v op= e<sub>2</sub></i> is equivalent to <i>((x) => x.v
@@ -6158,35 +6315,35 @@
 
   /**
    * The Dart Language Specification, 12.20: <blockquote>The static type of a logical boolean
-   * expression is {@code bool}.</blockquote>
-   * <p>
+   * expression is `bool`.</blockquote>
+   *
    * The Dart Language Specification, 12.21:<blockquote>A bitwise expression of the form
    * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
    * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A bitwise expression of the form <i>super op
    * e<sub>2</sub></i> is equivalent to the method invocation
    * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
-   * <p>
+   *
    * The Dart Language Specification, 12.22: <blockquote>The static type of an equality expression
-   * is {@code bool}.</blockquote>
-   * <p>
+   * is `bool`.</blockquote>
+   *
    * The Dart Language Specification, 12.23: <blockquote>A relational expression of the form
    * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
    * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A relational expression of the form <i>super op
    * e<sub>2</sub></i> is equivalent to the method invocation
    * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
-   * <p>
+   *
    * The Dart Language Specification, 12.24: <blockquote>A shift expression of the form
    * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
    * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A shift expression of the form <i>super op
    * e<sub>2</sub></i> is equivalent to the method invocation
    * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
-   * <p>
+   *
    * The Dart Language Specification, 12.25: <blockquote>An additive expression of the form
    * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
    * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. An additive expression of the form <i>super op
    * e<sub>2</sub></i> is equivalent to the method invocation
    * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
-   * <p>
+   *
    * The Dart Language Specification, 12.26: <blockquote>A multiplicative expression of the form
    * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
    * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A multiplicative expression of the form <i>super op
@@ -6231,9 +6388,9 @@
   /**
    * The Dart Language Specification, 12.19: <blockquote> ... a conditional expression <i>c</i> of
    * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ...
-   * <p>
-   * It is a static type warning if the type of e<sub>1</sub> may not be assigned to {@code bool}.
-   * <p>
+   *
+   * It is a static type warning if the type of e<sub>1</sub> may not be assigned to `bool`.
+   *
    * The static type of <i>c</i> is the least upper bound of the static type of <i>e<sub>2</sub></i>
    * and the static type of <i>e<sub>3</sub></i>.</blockquote>
    */
@@ -6278,8 +6435,10 @@
   }
   Object visitFunctionDeclaration(FunctionDeclaration node) {
     FunctionExpression function = node.functionExpression;
-    FunctionTypeImpl functionType = node.element.type as FunctionTypeImpl;
-    setTypeInformation(functionType, computeReturnType2(node), function.parameters);
+    ExecutableElementImpl functionElement = node.element as ExecutableElementImpl;
+    functionElement.returnType = computeReturnType2(node);
+    FunctionTypeImpl functionType = functionElement.type as FunctionTypeImpl;
+    setTypeInformation(functionType, function.parameters);
     recordStaticType(function, functionType);
     return null;
   }
@@ -6292,21 +6451,21 @@
    * x<sub>n+k</sub>\]) &rarr; T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is the static type of
    * <i>e</i>. In any case where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is
    * considered to have been specified as dynamic.
-   * <p>
+   *
    * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
    * T<sub>n</sub> a<sub>n</sub>, {T<sub>n+1</sub> x<sub>n+1</sub> : d1, &hellip;, T<sub>n+k</sub>
    * x<sub>n+k</sub> : dk}) => e</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>n+1</sub>
    * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; T<sub>0</sub></i>, where
    * <i>T<sub>0</sub></i> is the static type of <i>e</i>. In any case where <i>T<sub>i</sub>, 1
    * &lt;= i &lt;= n</i>, is not specified, it is considered to have been specified as dynamic.
-   * <p>
+   *
    * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
    * T<sub>n</sub> a<sub>n</sub>, \[T<sub>n+1</sub> x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub>
    * x<sub>n+k</sub> = dk\]) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, \[T<sub>n+1</sub>
    * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>\]) &rarr; dynamic</i>. In any case
    * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is considered to have been
    * specified as dynamic.
-   * <p>
+   *
    * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
    * T<sub>n</sub> a<sub>n</sub>, {T<sub>n+1</sub> x<sub>n+1</sub> : d1, &hellip;, T<sub>n+k</sub>
    * x<sub>n+k</sub> : dk}) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>n+1</sub>
@@ -6318,8 +6477,10 @@
     if (node.parent is FunctionDeclaration) {
       return null;
     }
+    ExecutableElementImpl functionElement = node.element as ExecutableElementImpl;
+    functionElement.returnType = computeReturnType3(node);
     FunctionTypeImpl functionType = node.element.type as FunctionTypeImpl;
-    setTypeInformation(functionType, computeReturnType3(node), node.parameters);
+    setTypeInformation(functionType, node.parameters);
     recordStaticType(node, functionType);
     return null;
   }
@@ -6329,10 +6490,10 @@
    * has the form <i>e<sub>f</sub>(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>:
    * a<sub>n+1</sub>, &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i>e<sub>f</sub></i> is
    * an expression.
-   * <p>
+   *
    * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub></i> may not be
    * assigned to a function type.
-   * <p>
+   *
    * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic. Otherwise the
    * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquote>
    */
@@ -6386,7 +6547,7 @@
    * The Dart Language Specification, 12.11.1: <blockquote>The static type of a new expression of
    * either the form <i>new T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the form <i>new
    * T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>.</blockquote>
-   * <p>
+   *
    * The Dart Language Specification, 12.11.2: <blockquote>The static type of a constant object
    * expression of either the form <i>const T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the
    * form <i>const T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>. </blockquote>
@@ -6407,7 +6568,7 @@
   }
 
   /**
-   * The Dart Language Specification, 12.3: <blockquote>The static type of an integer literal is{@code int}.</blockquote>
+   * The Dart Language Specification, 12.3: <blockquote>The static type of an integer literal is`int`.</blockquote>
    */
   Object visitIntegerLiteral(IntegerLiteral node) {
     recordStaticType(node, _typeProvider.intType);
@@ -6417,8 +6578,8 @@
   /**
    * The Dart Language Specification, 12.31: <blockquote>It is a static warning if <i>T</i> does not
    * denote a type available in the current lexical scope.
-   * <p>
-   * The static type of an is-expression is {@code bool}.</blockquote>
+   *
+   * The static type of an is-expression is `bool`.</blockquote>
    */
   Object visitIsExpression(IsExpression node) {
     recordStaticType(node, _typeProvider.boolType);
@@ -6428,9 +6589,9 @@
   /**
    * The Dart Language Specification, 12.6: <blockquote>The static type of a list literal of the
    * form <i><b>const</b> &lt;E&gt;\[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i> or the form
-   * <i>&lt;E&gt;\[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i> is {@code List&lt;E&gt;}. The static
+   * <i>&lt;E&gt;\[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i> is `List&lt;E&gt;`. The static
    * type a list literal of the form <i><b>const</b> \[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i> or
-   * the form <i>\[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i> is {@code List&lt;dynamic&gt;}.</blockquote>
+   * the form <i>\[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i> is `List&lt;dynamic&gt;`.</blockquote>
    */
   Object visitListLiteral(ListLiteral node) {
     Type2 staticType = _dynamicType;
@@ -6472,11 +6633,11 @@
    * The Dart Language Specification, 12.7: <blockquote>The static type of a map literal of the form
    * <i><b>const</b> &lt;String, V&gt; {k<sub>1</sub>:e<sub>1</sub>, &hellip;,
    * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>&lt;String, V&gt; {k<sub>1</sub>:e<sub>1</sub>,
-   * &hellip;, k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map&lt;String, V&gt;}. The static type a
+   * &hellip;, k<sub>n</sub>:e<sub>n</sub>}</i> is `Map&lt;String, V&gt;`. The static type a
    * map literal of the form <i><b>const</b> {k<sub>1</sub>:e<sub>1</sub>, &hellip;,
    * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>{k<sub>1</sub>:e<sub>1</sub>, &hellip;,
-   * k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map&lt;String, dynamic&gt;}.
-   * <p>
+   * k<sub>n</sub>:e<sub>n</sub>}</i> is `Map&lt;String, dynamic&gt;`.
+   *
    * It is a compile-time error if the first type argument to a map literal is not
    * <i>String</i>.</blockquote>
    */
@@ -6546,34 +6707,34 @@
    * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method invocation <i>i</i>
    * has the form <i>o.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
    * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
-   * <p>
+   *
    * Let <i>T</i> be the static type of <i>o</i>. It is a static type warning if <i>T</i> does not
    * have an accessible instance member named <i>m</i>. If <i>T.m</i> exists, it is a static warning
    * if the type <i>F</i> of <i>T.m</i> may not be assigned to a function type.
-   * <p>
+   *
    * If <i>T.m</i> does not exist, or if <i>F</i> is not a function type, the static type of
    * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
    * <i>F</i>.</blockquote>
-   * <p>
+   *
    * The Dart Language Specification, 11.15.3: <blockquote>A static method invocation <i>i</i> has
    * the form <i>C.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
    * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
-   * <p>
+   *
    * It is a static type warning if the type <i>F</i> of <i>C.m</i> may not be assigned to a
    * function type.
-   * <p>
+   *
    * If <i>F</i> is not a function type, or if <i>C.m</i> does not exist, the static type of i is
    * dynamic. Otherwise the static type of <i>i</i> is the declared return type of
    * <i>F</i>.</blockquote>
-   * <p>
+   *
    * The Dart Language Specification, 11.15.4: <blockquote>A super method invocation <i>i</i> has
    * the form <i>super.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
    * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
-   * <p>
+   *
    * It is a static type warning if <i>S</i> does not have an accessible instance member named m. If
    * <i>S.m</i> exists, it is a static warning if the type <i>F</i> of <i>S.m</i> may not be
    * assigned to a function type.
-   * <p>
+   *
    * If <i>S.m</i> does not exist, or if <i>F</i> is not a function type, the static type of
    * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
    * <i>F</i>.</blockquote>
@@ -6662,7 +6823,7 @@
   }
 
   /**
-   * The Dart Language Specification, 12.2: <blockquote>The static type of {@code null} is bottom.
+   * The Dart Language Specification, 12.2: <blockquote>The static type of `null` is bottom.
    * </blockquote>
    */
   Object visitNullLiteral(NullLiteral node) {
@@ -6680,25 +6841,25 @@
    * The Dart Language Specification, 12.28: <blockquote>A postfix expression of the form
    * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r = v; v = r + 1;
    * return r}()</i>.
-   * <p>
+   *
    * A postfix expression of the form <i>C.v++</i> is equivalent to <i>(){var r = C.v; C.v = r + 1;
    * return r}()</i>.
-   * <p>
+   *
    * A postfix expression of the form <i>e1.v++</i> is equivalent to <i>(x){var r = x.v; x.v = r +
    * 1; return r}(e1)</i>.
-   * <p>
+   *
    * A postfix expression of the form <i>e1\[e2\]++</i> is equivalent to <i>(a, i){var r = a\[i\]; a\[i\]
    * = r + 1; return r}(e1, e2)</i>
-   * <p>
+   *
    * A postfix expression of the form <i>v--</i>, where <i>v</i> is an identifier, is equivalent to
    * <i>(){var r = v; v = r - 1; return r}()</i>.
-   * <p>
+   *
    * A postfix expression of the form <i>C.v--</i> is equivalent to <i>(){var r = C.v; C.v = r - 1;
    * return r}()</i>.
-   * <p>
+   *
    * A postfix expression of the form <i>e1.v--</i> is equivalent to <i>(x){var r = x.v; x.v = r -
    * 1; return r}(e1)</i>.
-   * <p>
+   *
    * A postfix expression of the form <i>e1\[e2\]--</i> is equivalent to <i>(a, i){var r = a\[i\]; a\[i\]
    * = r - 1; return r}(e1, e2)</i></blockquote>
    */
@@ -6718,7 +6879,7 @@
   }
 
   /**
-   * See {@link #visitSimpleIdentifier(SimpleIdentifier)}.
+   * See [visitSimpleIdentifier].
    */
   Object visitPrefixedIdentifier(PrefixedIdentifier node) {
     SimpleIdentifier prefixedIdentifier = node.identifier;
@@ -6787,43 +6948,43 @@
    * The Dart Language Specification, 12.13: <blockquote> Property extraction allows for a member of
    * an object to be concisely extracted from the object. If <i>o</i> is an object, and if <i>m</i>
    * is the name of a method member of <i>o</i>, then
-   * <ul>
-   * <li><i>o.m</i> is defined to be equivalent to: <i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
+   *
+   * * <i>o.m</i> is defined to be equivalent to: <i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
    * {p<sub>1</sub> : d<sub>1</sub>, &hellip;, p<sub>k</sub> : d<sub>k</sub>}){return
    * o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>, p<sub>1</sub>: p<sub>1</sub>, &hellip;,
    * p<sub>k</sub>: p<sub>k</sub>);}</i> if <i>m</i> has required parameters <i>r<sub>1</sub>,
    * &hellip;, r<sub>n</sub></i>, and named parameters <i>p<sub>1</sub> &hellip; p<sub>k</sub></i>
-   * with defaults <i>d<sub>1</sub>, &hellip;, d<sub>k</sub></i>.</li>
-   * <li><i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>, \[p<sub>1</sub> = d<sub>1</sub>, &hellip;,
+   * with defaults <i>d<sub>1</sub>, &hellip;, d<sub>k</sub></i>.
+   * * <i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>, \[p<sub>1</sub> = d<sub>1</sub>, &hellip;,
    * p<sub>k</sub> = d<sub>k</sub>\]){return o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
    * p<sub>1</sub>, &hellip;, p<sub>k</sub>);}</i> if <i>m</i> has required parameters
    * <i>r<sub>1</sub>, &hellip;, r<sub>n</sub></i>, and optional positional parameters
    * <i>p<sub>1</sub> &hellip; p<sub>k</sub></i> with defaults <i>d<sub>1</sub>, &hellip;,
-   * d<sub>k</sub></i>.</li>
-   * </ul>
+   * d<sub>k</sub></i>.
+   *
    * Otherwise, if <i>m</i> is the name of a getter member of <i>o</i> (declared implicitly or
    * explicitly) then <i>o.m</i> evaluates to the result of invoking the getter. </blockquote>
-   * <p>
+   *
    * The Dart Language Specification, 12.17: <blockquote> ... a getter invocation <i>i</i> of the
    * form <i>e.m</i> ...
-   * <p>
+   *
    * Let <i>T</i> be the static type of <i>e</i>. It is a static type warning if <i>T</i> does not
    * have a getter named <i>m</i>.
-   * <p>
+   *
    * The static type of <i>i</i> is the declared return type of <i>T.m</i>, if <i>T.m</i> exists;
    * otherwise the static type of <i>i</i> is dynamic.
-   * <p>
+   *
    * ... a getter invocation <i>i</i> of the form <i>C.m</i> ...
-   * <p>
+   *
    * It is a static warning if there is no class <i>C</i> in the enclosing lexical scope of
    * <i>i</i>, or if <i>C</i> does not declare, implicitly or explicitly, a getter named <i>m</i>.
-   * <p>
+   *
    * The static type of <i>i</i> is the declared return type of <i>C.m</i> if it exists or dynamic
    * otherwise.
-   * <p>
+   *
    * ... a top-level getter invocation <i>i</i> of the form <i>m</i>, where <i>m</i> is an
    * identifier ...
-   * <p>
+   *
    * The static type of <i>i</i> is the declared return type of <i>m</i>.</blockquote>
    */
   Object visitPropertyAccess(PropertyAccess node) {
@@ -6857,43 +7018,43 @@
   /**
    * The Dart Language Specification, 12.30: <blockquote>Evaluation of an identifier expression
    * <i>e</i> of the form <i>id</i> proceeds as follows:
-   * <p>
+   *
    * Let <i>d</i> be the innermost declaration in the enclosing lexical scope whose name is
    * <i>id</i>. If no such declaration exists in the lexical scope, let <i>d</i> be the declaration
    * of the inherited member named <i>id</i> if it exists.
-   * <ul>
-   * <li>If <i>d</i> is a class or type alias <i>T</i>, the value of <i>e</i> is the unique instance
-   * of class {@code Type} reifying <i>T</i>.
-   * <li>If <i>d</i> is a type parameter <i>T</i>, then the value of <i>e</i> is the value of the
+   *
+   * * If <i>d</i> is a class or type alias <i>T</i>, the value of <i>e</i> is the unique instance
+   * of class `Type` reifying <i>T</i>.
+   * * If <i>d</i> is a type parameter <i>T</i>, then the value of <i>e</i> is the value of the
    * actual type argument corresponding to <i>T</i> that was passed to the generative constructor
    * that created the current binding of this. We are assured that this is well defined, because if
    * we were in a static member the reference to <i>T</i> would be a compile-time error.
-   * <li>If <i>d</i> is a library variable then:
-   * <ul>
-   * <li>If <i>d</i> is of one of the forms <i>var v = e<sub>i</sub>;</i>, <i>T v =
+   * * If <i>d</i> is a library variable then:
+   *
+   * * If <i>d</i> is of one of the forms <i>var v = e<sub>i</sub>;</i>, <i>T v =
    * e<sub>i</sub>;</i>, <i>final v = e<sub>i</sub>;</i>, <i>final T v = e<sub>i</sub>;</i>, and no
    * value has yet been stored into <i>v</i> then the initializer expression <i>e<sub>i</sub></i> is
    * evaluated. If, during the evaluation of <i>e<sub>i</sub></i>, the getter for <i>v</i> is
    * referenced, a CyclicInitializationError is thrown. If the evaluation succeeded yielding an
    * object <i>o</i>, let <i>r = o</i>, otherwise let <i>r = null</i>. In any case, <i>r</i> is
    * stored into <i>v</i>. The value of <i>e</i> is <i>r</i>.
-   * <li>If <i>d</i> is of one of the forms <i>const v = e;</i> or <i>const T v = e;</i> the result
+   * * If <i>d</i> is of one of the forms <i>const v = e;</i> or <i>const T v = e;</i> the result
    * of the getter is the value of the compile time constant <i>e</i>. Otherwise
-   * <li><i>e</i> evaluates to the current binding of <i>id</i>.
-   * </ul>
-   * <li>If <i>d</i> is a local variable or formal parameter then <i>e</i> evaluates to the current
+   * * <i>e</i> evaluates to the current binding of <i>id</i>.
+   *
+   * * If <i>d</i> is a local variable or formal parameter then <i>e</i> evaluates to the current
    * binding of <i>id</i>.
-   * <li>If <i>d</i> is a static method, top level function or local function then <i>e</i>
+   * * If <i>d</i> is a static method, top level function or local function then <i>e</i>
    * evaluates to the function defined by <i>d</i>.
-   * <li>If <i>d</i> is the declaration of a static variable or static getter declared in class
+   * * If <i>d</i> is the declaration of a static variable or static getter declared in class
    * <i>C</i>, then <i>e</i> is equivalent to the getter invocation <i>C.id</i>.
-   * <li>If <i>d</i> is the declaration of a top level getter, then <i>e</i> is equivalent to the
+   * * If <i>d</i> is the declaration of a top level getter, then <i>e</i> is equivalent to the
    * getter invocation <i>id</i>.
-   * <li>Otherwise, if <i>e</i> occurs inside a top level or static function (be it function,
+   * * Otherwise, if <i>e</i> occurs inside a top level or static function (be it function,
    * method, getter, or setter) or variable initializer, evaluation of e causes a NoSuchMethodError
    * to be thrown.
-   * <li>Otherwise <i>e</i> is equivalent to the property extraction <i>this.id</i>.
-   * </ul>
+   * * Otherwise <i>e</i> is equivalent to the property extraction <i>this.id</i>.
+   *
    * </blockquote>
    */
   Object visitSimpleIdentifier(SimpleIdentifier node) {
@@ -6931,7 +7092,7 @@
   }
 
   /**
-   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is{@code String}.</blockquote>
+   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is`String`.</blockquote>
    */
   Object visitSimpleStringLiteral(SimpleStringLiteral node) {
     recordStaticType(node, _typeProvider.stringType);
@@ -6939,7 +7100,7 @@
   }
 
   /**
-   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is{@code String}.</blockquote>
+   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is`String`.</blockquote>
    */
   Object visitStringInterpolation(StringInterpolation node) {
     recordStaticType(node, _typeProvider.stringType);
@@ -6955,7 +7116,7 @@
   }
 
   /**
-   * The Dart Language Specification, 12.10: <blockquote>The static type of {@code this} is the
+   * The Dart Language Specification, 12.10: <blockquote>The static type of `this` is the
    * interface of the immediately enclosing class.</blockquote>
    */
   Object visitThisExpression(ThisExpression node) {
@@ -7025,7 +7186,7 @@
           if (innerReturnType != null) {
             return innerReturnType;
           }
-        } else if (returnType.isDartCoreFunction()) {
+        } else if (returnType.isDartCoreFunction) {
           return _dynamicType;
         }
         if (returnType != null) {
@@ -7048,7 +7209,7 @@
 
   /**
    * Given a function declaration, compute the return type of the function. The return type of
-   * functions with a block body is {@code dynamicType}, with an expression body it is the type of
+   * functions with a block body is `dynamicType`, with an expression body it is the type of
    * the expression.
    * @param node the function expression whose return type is to be computed
    * @return the return type that was computed
@@ -7063,7 +7224,7 @@
 
   /**
    * Given a function expression, compute the return type of the function. The return type of
-   * functions with a block body is {@code dynamicType}, with an expression body it is the type of
+   * functions with a block body is `dynamicType`, with an expression body it is the type of
    * the expression.
    * @param node the function expression whose return type is to be computed
    * @return the return type that was computed
@@ -7196,7 +7357,7 @@
   /**
    * Return the type that should be recorded for a node that resolved to the given accessor.
    * @param accessor the accessor that the node resolved to
-   * @param context if the accessor element has context \[by being the RHS of a{@link PrefixedIdentifier} or {@link PropertyAccess}\], and the return type of the
+   * @param context if the accessor element has context \[by being the RHS of a[PrefixedIdentifier] or [PropertyAccess]\], and the return type of the
    * accessor is a parameter type, then the type of the LHS can be used to get more
    * specific type information
    * @return the type that should be recorded for a node that resolved to the given accessor
@@ -7206,7 +7367,7 @@
     if (functionType == null) {
       return _dynamicType;
     }
-    if (accessor.isSetter()) {
+    if (accessor.isSetter) {
       List<Type2> parameterTypes = functionType.normalParameterTypes;
       if (parameterTypes != null && parameterTypes.length > 0) {
         return parameterTypes[0];
@@ -7250,16 +7411,16 @@
   }
 
   /**
-   * Return {@code true} if the given library is the 'dart:html' library.
+   * Return `true` if the given library is the 'dart:html' library.
    * @param library the library being tested
-   * @return {@code true} if the library is 'dart:html'
+   * @return `true` if the library is 'dart:html'
    */
   bool isHtmlLibrary(LibraryElement library) => library.name == "dart.dom.html";
 
   /**
-   * Return {@code true} if the given node is not a type literal.
+   * Return `true` if the given node is not a type literal.
    * @param node the node being tested
-   * @return {@code true} if the given node is not a type literal
+   * @return `true` if the given node is not a type literal
    */
   bool isNotTypeLiteral(Identifier node) {
     ASTNode parent = node.parent;
@@ -7272,7 +7433,7 @@
    * @param type the propagated type of the node
    */
   void recordPropagatedType(Expression expression, Type2 type) {
-    if (type != null && !type.isDynamic()) {
+    if (type != null && !type.isDynamic) {
       expression.propagatedType = type;
     }
   }
@@ -7320,10 +7481,9 @@
    * Set the return type and parameter type information for the given function type based on the
    * given return type and parameter elements.
    * @param functionType the function type to be filled in
-   * @param returnType the return type of the function, or {@code null} if no type was declared
    * @param parameters the elements representing the parameters to the function
    */
-  void setTypeInformation(FunctionTypeImpl functionType, Type2 returnType2, FormalParameterList parameterList) {
+  void setTypeInformation(FunctionTypeImpl functionType, FormalParameterList parameterList) {
     List<Type2> normalParameterTypes = new List<Type2>();
     List<Type2> optionalParameterTypes = new List<Type2>();
     LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
@@ -7344,19 +7504,18 @@
     functionType.normalParameterTypes = new List.from(normalParameterTypes);
     functionType.optionalParameterTypes = new List.from(optionalParameterTypes);
     functionType.namedParameterTypes = namedParameterTypes;
-    functionType.returnType = returnType2;
   }
   get thisType_J2DAccessor => _thisType;
   set thisType_J2DAccessor(__v) => _thisType = __v;
 }
 /**
- * Instances of the class {@code TypeOverrideManager} manage the ability to override the type of an
+ * Instances of the class `TypeOverrideManager` manage the ability to override the type of an
  * element within a given context.
  */
 class TypeOverrideManager {
 
   /**
-   * The current override scope, or {@code null} if no scope has been entered.
+   * The current override scope, or `null` if no scope has been entered.
    */
   TypeOverrideManager_TypeOverrideScope _currentScope;
 
@@ -7414,7 +7573,7 @@
   }
 
   /**
-   * Return the overridden type of the given element, or {@code null} if the type of the element has
+   * Return the overridden type of the given element, or `null` if the type of the element has
    * not been overridden.
    * @param element the element whose type might have been overridden
    * @return the overridden type of the given element
@@ -7439,7 +7598,7 @@
   }
 }
 /**
- * Instances of the class {@code TypeOverrideScope} represent a scope in which the types of
+ * Instances of the class `TypeOverrideScope` represent a scope in which the types of
  * elements can be overridden.
  */
 class TypeOverrideManager_TypeOverrideScope {
@@ -7487,7 +7646,7 @@
    */
   Map<Element, Type2> captureOverrides(VariableDeclarationList variableList) {
     Map<Element, Type2> overrides = new Map<Element, Type2>();
-    if (variableList.isConst() || variableList.isFinal()) {
+    if (variableList.isConst || variableList.isFinal) {
       for (VariableDeclaration variable in variableList.variables) {
         Element element = variable.element;
         if (element != null) {
@@ -7502,7 +7661,7 @@
   }
 
   /**
-   * Return the overridden type of the given element, or {@code null} if the type of the element
+   * Return the overridden type of the given element, or `null` if the type of the element
    * has not been overridden.
    * @param element the element whose type might have been overridden
    * @return the overridden type of the given element
@@ -7530,7 +7689,7 @@
   }
 }
 /**
- * The interface {@code TypeProvider} defines the behavior of objects that provide access to types
+ * The interface `TypeProvider` defines the behavior of objects that provide access to types
  * defined by the language.
  * @coverage dart.engine.resolver
  */
@@ -7615,7 +7774,7 @@
   InterfaceType get typeType;
 }
 /**
- * Instances of the class {@code TypeProviderImpl} provide access to types defined by the language
+ * Instances of the class `TypeProviderImpl` provide access to types defined by the language
  * by looking for those types in the element model for the core library.
  * @coverage dart.engine.resolver
  */
@@ -7708,7 +7867,7 @@
   InterfaceType get typeType => _typeType;
 
   /**
-   * Return the type with the given name from the given namespace, or {@code null} if there is no
+   * Return the type with the given name from the given namespace, or `null` if there is no
    * class with the given name.
    * @param namespace the namespace in which to search for the given name
    * @param typeName the name of the type being searched for
@@ -7745,7 +7904,7 @@
   }
 }
 /**
- * Instances of the class {@code TypeResolverVisitor} are used to resolve the types associated with
+ * Instances of the class `TypeResolverVisitor` are used to resolve the types associated with
  * the elements in the element model. This includes the types of superclasses, mixins, interfaces,
  * fields, methods, parameters, and local variables. As a side-effect, this also finishes building
  * the type hierarchy.
@@ -7770,9 +7929,9 @@
    * @param typeProvider the object used to access the types from the core library
    */
   TypeResolverVisitor.con1(Library library, Source source, TypeProvider typeProvider) : super.con1(library, source, typeProvider) {
-    _jtd_constructor_281_impl(library, source, typeProvider);
+    _jtd_constructor_282_impl(library, source, typeProvider);
   }
-  _jtd_constructor_281_impl(Library library, Source source, TypeProvider typeProvider) {
+  _jtd_constructor_282_impl(Library library, Source source, TypeProvider typeProvider) {
     _dynamicType = typeProvider.dynamicType;
   }
 
@@ -7786,9 +7945,9 @@
    * during resolution
    */
   TypeResolverVisitor.con2(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) : super.con2(definingLibrary, source, typeProvider, errorListener) {
-    _jtd_constructor_282_impl(definingLibrary, source, typeProvider, errorListener);
+    _jtd_constructor_283_impl(definingLibrary, source, typeProvider, errorListener);
   }
-  _jtd_constructor_282_impl(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) {
+  _jtd_constructor_283_impl(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) {
     _dynamicType = typeProvider.dynamicType;
   }
   Object visitCatchClause(CatchClause node) {
@@ -7857,9 +8016,11 @@
   Object visitConstructorDeclaration(ConstructorDeclaration node) {
     super.visitConstructorDeclaration(node);
     ExecutableElementImpl element = node.element as ExecutableElementImpl;
+    ClassElement definingClass = element.enclosingElement as ClassElement;
+    element.returnType = definingClass.type;
     FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
-    setTypeInformation(type, null, element.parameters);
-    type.returnType = ((element.enclosingElement as ClassElement)).type;
+    type.typeArguments = definingClass.type.typeArguments;
+    setTypeInformation(type, element.parameters);
     element.type = type;
     return null;
   }
@@ -7900,38 +8061,65 @@
   Object visitFunctionDeclaration(FunctionDeclaration node) {
     super.visitFunctionDeclaration(node);
     ExecutableElementImpl element = node.element as ExecutableElementImpl;
+    element.returnType = computeReturnType(node.returnType);
     FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
-    setTypeInformation(type, node.returnType, element.parameters);
+    ClassElement definingClass = element.getAncestor(ClassElement);
+    if (definingClass != null) {
+      type.typeArguments = definingClass.type.typeArguments;
+    }
+    setTypeInformation(type, element.parameters);
     element.type = type;
     return null;
   }
   Object visitFunctionTypeAlias(FunctionTypeAlias node) {
     super.visitFunctionTypeAlias(node);
     FunctionTypeAliasElementImpl element = node.element as FunctionTypeAliasElementImpl;
+    element.returnType = computeReturnType(node.returnType);
     FunctionTypeImpl type = element.type as FunctionTypeImpl;
-    setTypeInformation(type, node.returnType, element.parameters);
+    setTypeInformation(type, element.parameters);
     return null;
   }
   Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
     super.visitFunctionTypedFormalParameter(node);
     ParameterElementImpl element = node.identifier.element as ParameterElementImpl;
-    AnonymousFunctionTypeImpl type = new AnonymousFunctionTypeImpl();
     List<ParameterElement> parameters = getElements(node.parameters);
-    setTypeInformation(type, node.returnType, parameters);
-    type.baseParameters = parameters;
+    FunctionTypeAliasElementImpl aliasElement = new FunctionTypeAliasElementImpl(null);
+    aliasElement.synthetic = true;
+    aliasElement.parameters = parameters;
+    aliasElement.returnType = computeReturnType(node.returnType);
+    FunctionTypeImpl type = new FunctionTypeImpl.con2(aliasElement);
+    ClassElement definingClass = element.getAncestor(ClassElement);
+    if (definingClass != null) {
+      aliasElement.typeVariables = definingClass.typeVariables;
+      type.typeArguments = definingClass.type.typeArguments;
+    } else {
+      FunctionTypeAliasElement alias = element.getAncestor(FunctionTypeAliasElement);
+      if (alias != null) {
+        aliasElement.typeVariables = alias.typeVariables;
+        type.typeArguments = alias.type.typeArguments;
+      } else {
+        type.typeArguments = TypeVariableTypeImpl.EMPTY_ARRAY;
+      }
+    }
+    setTypeInformation(type, parameters);
     element.type = type;
     return null;
   }
   Object visitMethodDeclaration(MethodDeclaration node) {
     super.visitMethodDeclaration(node);
     ExecutableElementImpl element = node.element as ExecutableElementImpl;
+    element.returnType = computeReturnType(node.returnType);
     FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
-    setTypeInformation(type, node.returnType, element.parameters);
+    ClassElement definingClass = element.getAncestor(ClassElement);
+    if (definingClass != null) {
+      type.typeArguments = definingClass.type.typeArguments;
+    }
+    setTypeInformation(type, element.parameters);
     element.type = type;
     if (element is PropertyAccessorElement) {
       PropertyAccessorElement accessor = element as PropertyAccessorElement;
       PropertyInducingElementImpl variable = accessor.variable as PropertyInducingElementImpl;
-      if (accessor.isGetter()) {
+      if (accessor.isGetter) {
         variable.type = type.returnType;
       } else if (variable.type == null) {
         List<Type2> parameterTypes = type.normalParameterTypes;
@@ -8005,7 +8193,7 @@
     if (elementValid && element is! ClassElement && isTypeNameInInstanceCreationExpression(node)) {
       SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName);
       InstanceCreationExpression creation = node.parent.parent as InstanceCreationExpression;
-      if (creation.isConst()) {
+      if (creation.isConst) {
         if (element == null) {
           reportError(CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [typeName]);
         } else {
@@ -8143,13 +8331,20 @@
       if (element is PropertyInducingElement) {
         PropertyInducingElement variableElement = element as PropertyInducingElement;
         PropertyAccessorElementImpl getter = variableElement.getter as PropertyAccessorElementImpl;
+        getter.returnType = declaredType;
         FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
-        getterType.returnType = declaredType;
+        ClassElement definingClass = element.getAncestor(ClassElement);
+        if (definingClass != null) {
+          getterType.typeArguments = definingClass.type.typeArguments;
+        }
         getter.type = getterType;
         PropertyAccessorElementImpl setter = variableElement.setter as PropertyAccessorElementImpl;
         if (setter != null) {
+          setter.returnType = VoidTypeImpl.instance;
           FunctionTypeImpl setterType = new FunctionTypeImpl.con1(setter);
-          setterType.returnType = VoidTypeImpl.instance;
+          if (definingClass != null) {
+            setterType.typeArguments = definingClass.type.typeArguments;
+          }
           setterType.normalParameterTypes = <Type2> [declaredType];
           setter.type = setterType;
         }
@@ -8160,6 +8355,20 @@
   }
 
   /**
+   * Given a type name representing the return type of a function, compute the return type of the
+   * function.
+   * @param returnType the type name representing the return type of the function
+   * @return the return type that was computed
+   */
+  Type2 computeReturnType(TypeName returnType) {
+    if (returnType == null) {
+      return _dynamicType;
+    } else {
+      return returnType.type;
+    }
+  }
+
+  /**
    * Return the class element that represents the class whose name was provided.
    * @param identifier the name from the declaration of a class
    * @return the class element that represents the class
@@ -8205,7 +8414,7 @@
     if (parent is ConstructorName) {
       parent = parent.parent;
       if (parent is InstanceCreationExpression) {
-        if (((parent as InstanceCreationExpression)).isConst()) {
+        if (((parent as InstanceCreationExpression)).isConst) {
           return CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS;
         } else {
           return CompileTimeErrorCode.NEW_WITH_INVALID_TYPE_PARAMETERS;
@@ -8217,7 +8426,7 @@
 
   /**
    * Given the multiple elements to which a single name could potentially be resolved, return the
-   * single interface type that should be used, or {@code null} if there is no clear choice.
+   * single interface type that should be used, or `null` if there is no clear choice.
    * @param elements the elements to which a single name could potentially be resolved
    * @return the single interface type that should be used for the type name
    */
@@ -8277,7 +8486,7 @@
   /**
    * Checks if the given type name is used as the type in an as expression.
    * @param typeName the type name to analyzer
-   * @return {@code true} if the given type name is used as the type in an as expression
+   * @return `true` if the given type name is used as the type in an as expression
    */
   bool isTypeNameInAsExpression(TypeName typeName) {
     ASTNode parent = typeName.parent;
@@ -8291,7 +8500,7 @@
   /**
    * Checks if the given type name is used as the exception type in a catch clause.
    * @param typeName the type name to analyzer
-   * @return {@code true} if the given type name is used as the exception type in a catch clause
+   * @return `true` if the given type name is used as the exception type in a catch clause
    */
   bool isTypeNameInCatchClause(TypeName typeName) {
     ASTNode parent = typeName.parent;
@@ -8305,7 +8514,7 @@
   /**
    * Checks if the given type name is used as the type in an instance creation expression.
    * @param typeName the type name to analyzer
-   * @return {@code true} if the given type name is used as the type in an instance creation
+   * @return `true` if the given type name is used as the type in an instance creation
    * expression
    */
   bool isTypeNameInInstanceCreationExpression(TypeName typeName) {
@@ -8320,7 +8529,7 @@
   /**
    * Checks if the given type name is used as the type in an is expression.
    * @param typeName the type name to analyzer
-   * @return {@code true} if the given type name is used as the type in an is expression
+   * @return `true` if the given type name is used as the type in an is expression
    */
   bool isTypeNameInIsExpression(TypeName typeName) {
     ASTNode parent = typeName.parent;
@@ -8334,7 +8543,7 @@
   /**
    * Checks if the given type name is the target in a redirected constructor.
    * @param typeName the type name to analyzer
-   * @return {@code true} if the given type name is used as the type in a redirected constructor
+   * @return `true` if the given type name is used as the type in a redirected constructor
    */
   bool isTypeNameTargetInRedirectedConstructor(TypeName typeName) {
     ASTNode parent = typeName.parent;
@@ -8472,10 +8681,9 @@
    * Set the return type and parameter type information for the given function type based on the
    * given return type and parameter elements.
    * @param functionType the function type to be filled in
-   * @param returnType the return type of the function, or {@code null} if no type was declared
    * @param parameters the elements representing the parameters to the function
    */
-  void setTypeInformation(FunctionTypeImpl functionType, TypeName returnType2, List<ParameterElement> parameters) {
+  void setTypeInformation(FunctionTypeImpl functionType, List<ParameterElement> parameters) {
     List<Type2> normalParameterTypes = new List<Type2>();
     List<Type2> optionalParameterTypes = new List<Type2>();
     LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
@@ -8500,15 +8708,10 @@
     if (!namedParameterTypes.isEmpty) {
       functionType.namedParameterTypes = namedParameterTypes;
     }
-    if (returnType2 == null) {
-      functionType.returnType = _dynamicType;
-    } else {
-      functionType.returnType = returnType2.type;
-    }
   }
 }
 /**
- * Instances of the class {@code ClassScope} implement the scope defined by a class.
+ * Instances of the class `ClassScope` implement the scope defined by a class.
  * @coverage dart.engine.resolver
  */
 class ClassScope extends EnclosedScope {
@@ -8558,7 +8761,7 @@
   }
 }
 /**
- * Instances of the class {@code EnclosedScope} implement a scope that is lexically enclosed in
+ * Instances of the class `EnclosedScope` implement a scope that is lexically enclosed in
  * another scope.
  * @coverage dart.engine.resolver
  */
@@ -8593,7 +8796,7 @@
   }
 }
 /**
- * Instances of the class {@code FunctionScope} implement the scope defined by a function.
+ * Instances of the class `FunctionScope` implement the scope defined by a function.
  * @coverage dart.engine.resolver
  */
 class FunctionScope extends EnclosedScope {
@@ -8620,14 +8823,14 @@
       }
     }
     for (ParameterElement parameter in functionElement.parameters) {
-      if (!parameter.isInitializingFormal()) {
+      if (!parameter.isInitializingFormal) {
         parameterScope.define(parameter);
       }
     }
   }
 }
 /**
- * Instances of the class {@code FunctionTypeScope} implement the scope defined by a function type
+ * Instances of the class `FunctionTypeScope` implement the scope defined by a function type
  * alias.
  * @coverage dart.engine.resolver
  */
@@ -8665,7 +8868,7 @@
   }
 }
 /**
- * Instances of the class {@code LabelScope} represent a scope in which a single label is defined.
+ * Instances of the class `LabelScope` represent a scope in which a single label is defined.
  * @coverage dart.engine.resolver
  */
 class LabelScope {
@@ -8686,26 +8889,26 @@
   LabelElement _element;
 
   /**
-   * The marker used to look up a label element for an unlabeled {@code break} or {@code continue}.
+   * The marker used to look up a label element for an unlabeled `break` or `continue`.
    */
   static String EMPTY_LABEL = "";
 
   /**
-   * The label element returned for scopes that can be the target of an unlabeled {@code break} or{@code continue}.
+   * The label element returned for scopes that can be the target of an unlabeled `break` or`continue`.
    */
   static SimpleIdentifier _EMPTY_LABEL_IDENTIFIER = new SimpleIdentifier.full(new sc.StringToken(sc.TokenType.IDENTIFIER, "", 0));
 
   /**
-   * Initialize a newly created scope to represent the potential target of an unlabeled{@code break} or {@code continue}.
+   * Initialize a newly created scope to represent the potential target of an unlabeled`break` or `continue`.
    * @param outerScope the label scope enclosing the new label scope
-   * @param onSwitchStatement {@code true} if this label is associated with a {@code switch}statement
-   * @param onSwitchMember {@code true} if this label is associated with a {@code switch} member
+   * @param onSwitchStatement `true` if this label is associated with a `switch`statement
+   * @param onSwitchMember `true` if this label is associated with a `switch` member
    */
   LabelScope.con1(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
-    _jtd_constructor_287_impl(outerScope, onSwitchStatement, onSwitchMember);
+    _jtd_constructor_288_impl(outerScope, onSwitchStatement, onSwitchMember);
   }
-  _jtd_constructor_287_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
-    _jtd_constructor_288_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMPTY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember));
+  _jtd_constructor_288_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
+    _jtd_constructor_289_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMPTY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember));
   }
 
   /**
@@ -8715,16 +8918,16 @@
    * @param element the element to which the label resolves
    */
   LabelScope.con2(LabelScope outerScope2, String label2, LabelElement element2) {
-    _jtd_constructor_288_impl(outerScope2, label2, element2);
+    _jtd_constructor_289_impl(outerScope2, label2, element2);
   }
-  _jtd_constructor_288_impl(LabelScope outerScope2, String label2, LabelElement element2) {
+  _jtd_constructor_289_impl(LabelScope outerScope2, String label2, LabelElement element2) {
     this._outerScope = outerScope2;
     this._label = label2;
     this._element = element2;
   }
 
   /**
-   * Return the label element corresponding to the given label, or {@code null} if the given label
+   * Return the label element corresponding to the given label, or `null` if the given label
    * is not defined in this scope.
    * @param targetLabel the label being looked up
    * @return the label element corresponding to the given label
@@ -8732,7 +8935,7 @@
   LabelElement lookup(SimpleIdentifier targetLabel) => lookup2(targetLabel.name);
 
   /**
-   * Return the label element corresponding to the given label, or {@code null} if the given label
+   * Return the label element corresponding to the given label, or `null` if the given label
    * is not defined in this scope.
    * @param targetLabel the label being looked up
    * @return the label element corresponding to the given label
@@ -8748,14 +8951,14 @@
   }
 }
 /**
- * Instances of the class {@code LibraryImportScope} represent the scope containing all of the names
+ * Instances of the class `LibraryImportScope` represent the scope containing all of the names
  * available from imported libraries.
  * @coverage dart.engine.resolver
  */
 class LibraryImportScope extends Scope {
 
   /**
-   * @return {@code true} if the given {@link Identifier} is the part of type annotation.
+   * @return `true` if the given [Identifier] is the part of type annotation.
    */
   static bool isTypeAnnotation(Identifier identifier) {
     ASTNode parent = identifier.parent;
@@ -8884,7 +9087,7 @@
   }
 }
 /**
- * Instances of the class {@code LibraryScope} implement a scope containing all of the names defined
+ * Instances of the class `LibraryScope` implement a scope containing all of the names defined
  * in a given library.
  * @coverage dart.engine.resolver
  */
@@ -8903,7 +9106,7 @@
       int offset = duplicate.nameOffset;
       if (duplicate is PropertyAccessorElement) {
         PropertyAccessorElement accessor = duplicate as PropertyAccessorElement;
-        if (accessor.isSynthetic()) {
+        if (accessor.isSynthetic) {
           offset = accessor.variable.nameOffset;
         }
       }
@@ -8949,7 +9152,7 @@
   }
 }
 /**
- * Instances of the class {@code Namespace} implement a mapping of identifiers to the elements
+ * Instances of the class `Namespace` implement a mapping of identifiers to the elements
  * represented by those identifiers. Namespaces are the building blocks for scopes.
  * @coverage dart.engine.resolver
  */
@@ -8990,14 +9193,14 @@
   Map<String, Element> get definedNames => new Map<String, Element>.from(_definedNames);
 }
 /**
- * Instances of the class {@code NamespaceBuilder} are used to build a {@code Namespace}. Namespace
+ * Instances of the class `NamespaceBuilder` are used to build a `Namespace`. Namespace
  * builders are thread-safe and re-usable.
  * @coverage dart.engine.resolver
  */
 class NamespaceBuilder {
 
   /**
-   * Create a namespace representing the export namespace of the given {@link ExportElement}.
+   * Create a namespace representing the export namespace of the given [ExportElement].
    * @param element the export element whose export namespace is to be created
    * @return the export namespace that was created
    */
@@ -9202,7 +9405,7 @@
   }
 }
 /**
- * The abstract class {@code Scope} defines the behavior common to name scopes used by the resolver
+ * The abstract class `Scope` defines the behavior common to name scopes used by the resolver
  * to determine which names are visible at any given point in the code.
  * @coverage dart.engine.resolver
  */
@@ -9226,9 +9429,9 @@
   static String UNARY_MINUS = "unary-";
 
   /**
-   * Return {@code true} if the given name is a library-private name.
+   * Return `true` if the given name is a library-private name.
    * @param name the name being tested
-   * @return {@code true} if the given name is a library-private name
+   * @return `true` if the given name is a library-private name
    */
   static bool isPrivateName(String name) => name != null && name.startsWith(PRIVATE_NAME_PREFIX);
 
@@ -9257,7 +9460,7 @@
   }
 
   /**
-   * Return the element with which the given identifier is associated, or {@code null} if the name
+   * Return the element with which the given identifier is associated, or `null` if the name
    * is not defined within this scope.
    * @param identifier the identifier associated with the element to be returned
    * @param referencingLibrary the library that contains the reference to the name, used to
@@ -9318,7 +9521,7 @@
   Source get source => definingLibrary.definingCompilationUnit.source;
 
   /**
-   * Return the element with which the given name is associated, or {@code null} if the name is not
+   * Return the element with which the given name is associated, or `null` if the name is not
    * defined within this scope. This method only returns elements that are directly defined within
    * this scope, not elements that are defined in an enclosing scope.
    * @param name the name associated with the element to be returned
@@ -9329,7 +9532,7 @@
   Element localLookup(String name, LibraryElement referencingLibrary) => _definedNames[name];
 
   /**
-   * Return the element with which the given name is associated, or {@code null} if the name is not
+   * Return the element with which the given name is associated, or `null` if the name is not
    * defined within this scope.
    * @param identifier the identifier node to lookup element for, used to report correct kind of a
    * problem and associate problem with
@@ -9356,7 +9559,7 @@
   }
 }
 /**
- * Instances of the class {@code ConstantVerifier} traverse an AST structure looking for additional
+ * Instances of the class `ConstantVerifier` traverse an AST structure looking for additional
  * errors and warnings not covered by the parser and resolver. In particular, it looks for errors
  * and warnings related to constant expressions.
  * @coverage dart.engine.resolver
@@ -9403,6 +9606,7 @@
     if (node.constKeyword != null) {
       validateInitializers(node);
     }
+    validateDefaultValues(node.parameters);
     return super.visitConstructorDeclaration(node);
   }
   Object visitFunctionExpression(FunctionExpression node) {
@@ -9476,7 +9680,7 @@
   Object visitVariableDeclaration(VariableDeclaration node) {
     super.visitVariableDeclaration(node);
     Expression initializer = node.initializer;
-    if (initializer != null && node.isConst()) {
+    if (initializer != null && node.isConst) {
       VariableElementImpl element = node.element as VariableElementImpl;
       EvaluationResultImpl result = element.evaluationResult;
       if (result == null) {
@@ -9490,11 +9694,11 @@
   }
 
   /**
-   * Return {@code true} if the given value is the result of evaluating an expression whose value is
+   * Return `true` if the given value is the result of evaluating an expression whose value is
    * a valid key in a const map literal. Keys in const map literals must be either a string, number,
    * boolean, list, map, or null.
    * @param value
-   * @return {@code true} if the given value is a valid key in a const map literal
+   * @return `true` if the given value is a valid key in a const map literal
    */
   bool isValidConstMapKey(Object value) => true;
 
@@ -9519,7 +9723,7 @@
 
   /**
    * Validate that the given expression is a compile time constant. Return the value of the compile
-   * time constant, or {@code null} if the expression is not a compile time constant.
+   * time constant, or `null` if the expression is not a compile time constant.
    * @param expression the expression to be validated
    * @param errorCode the error code to be used if the expression is not a compile time constant
    * @return the value of the compile time constant
@@ -9536,7 +9740,7 @@
    * @param node the instance creation evaluate
    */
   void validateConstantArguments(InstanceCreationExpression node) {
-    if (!node.isConst()) {
+    if (!node.isConst) {
       return;
     }
     ArgumentList argumentList = node.argumentList;
@@ -9566,10 +9770,8 @@
         Expression defaultValue = defaultParameter.defaultValue;
         if (defaultValue != null) {
           EvaluationResultImpl result = validate(defaultValue, CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE);
-          if (defaultParameter.isConst()) {
-            VariableElementImpl element = parameter.element as VariableElementImpl;
-            element.evaluationResult = result;
-          }
+          VariableElementImpl element = parameter.element as VariableElementImpl;
+          element.evaluationResult = result;
         }
       }
     }
@@ -9635,7 +9837,7 @@
       if (identical(parameterElement, element) && parameterElement != null) {
         Type2 type = parameterElement.type;
         if (type != null) {
-          if (type.isDynamic()) {
+          if (type.isDynamic) {
             return ValidResult.RESULT_DYNAMIC;
           }
           if (type.isSubtypeOf(ConstantVerifier_this._boolType)) {
@@ -9658,7 +9860,7 @@
   }
 }
 /**
- * Instances of the class {@code ErrorVerifier} traverse an AST structure looking for additional
+ * Instances of the class `ErrorVerifier` traverse an AST structure looking for additional
  * errors and warnings not covered by the parser and resolver.
  * @coverage dart.engine.resolver
  */
@@ -9667,7 +9869,7 @@
   /**
    * Checks if the given expression is the reference to the type.
    * @param expr the expression to evaluate
-   * @return {@code true} if the given expression is the reference to the type
+   * @return `true` if the given expression is the reference to the type
    */
   static bool isTypeReference(Expression expr) {
     if (expr is Identifier) {
@@ -9709,47 +9911,47 @@
   bool _strictMode = false;
 
   /**
-   * This is set to {@code true} iff the visitor is currently visiting children nodes of a{@link ConstructorDeclaration} and the constructor is 'const'.
+   * This is set to `true` iff the visitor is currently visiting children nodes of a[ConstructorDeclaration] and the constructor is 'const'.
    * @see #visitConstructorDeclaration(ConstructorDeclaration)
    */
   bool _isEnclosingConstructorConst = false;
 
   /**
-   * This is set to {@code true} iff the visitor is currently visiting children nodes of a{@link CatchClause}.
+   * This is set to `true` iff the visitor is currently visiting children nodes of a[CatchClause].
    * @see #visitCatchClause(CatchClause)
    */
   bool _isInCatchClause = false;
 
   /**
-   * This is set to {@code true} iff the visitor is currently visiting a{@link ConstructorInitializer}.
+   * This is set to `true` iff the visitor is currently visiting a[ConstructorInitializer].
    */
   bool _isInConstructorInitializer = false;
 
   /**
-   * This is set to {@code true} iff the visitor is currently visiting code in the SDK.
+   * This is set to `true` iff the visitor is currently visiting code in the SDK.
    */
   bool _isInSystemLibrary = false;
 
   /**
-   * The class containing the AST nodes being visited, or {@code null} if we are not in the scope of
+   * The class containing the AST nodes being visited, or `null` if we are not in the scope of
    * a class.
    */
   ClassElement _enclosingClass;
 
   /**
-   * The method or function that we are currently visiting, or {@code null} if we are not inside a
+   * The method or function that we are currently visiting, or `null` if we are not inside a
    * method or function.
    */
   ExecutableElement _enclosingFunction;
 
   /**
    * This map is initialized when visiting the contents of a class declaration. If the visitor is
-   * not in an enclosing class declaration, then the map is set to {@code null}.
-   * <p>
-   * When set the map maps the set of {@link FieldElement}s in the class to an{@link INIT_STATE#NOT_INIT} or {@link INIT_STATE#INIT_IN_DECLARATION}. <code>checkFor*</code>
-   * methods, specifically {@link #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration)},
+   * not in an enclosing class declaration, then the map is set to `null`.
+   *
+   * When set the map maps the set of [FieldElement]s in the class to an[INIT_STATE#NOT_INIT] or [INIT_STATE#INIT_IN_DECLARATION]. <code>checkFor*</code>
+   * methods, specifically [checkForAllFinalInitializedErrorCodes],
    * can make a copy of the map to compute error code states. <code>checkFor*</code> methods should
-   * only ever make a copy, or read from this map after it has been set in{@link #visitClassDeclaration(ClassDeclaration)}.
+   * only ever make a copy, or read from this map after it has been set in[visitClassDeclaration].
    * @see #visitClassDeclaration(ClassDeclaration)
    * @see #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration)
    */
@@ -9776,13 +9978,13 @@
   Set<String> _namesForReferenceToDeclaredVariableInInitializer = new Set<String>();
 
   /**
-   * A list of types used by the {@link CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS} and{@link CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS} error codes.
+   * A list of types used by the [CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS] and[CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS] error codes.
    */
   List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT;
   ErrorVerifier(ErrorReporter errorReporter, LibraryElement currentLibrary, TypeProvider typeProvider, InheritanceManager inheritanceManager) {
     this._errorReporter = errorReporter;
     this._currentLibrary = currentLibrary;
-    this._isInSystemLibrary = currentLibrary.source.isInSystemLibrary();
+    this._isInSystemLibrary = currentLibrary.source.isInSystemLibrary;
     this._typeProvider = typeProvider;
     this._inheritanceManager = inheritanceManager;
     _strictMode = currentLibrary.context.analysisOptions.strictMode;
@@ -9836,6 +10038,7 @@
       ExtendsClause extendsClause = node.extendsClause;
       checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
       checkForMemberWithClassName();
+      checkForNoDefaultSuperConstructorImplicit(node);
       checkForAllMixinErrorCodes(withClause);
       if (implementsClause != null || extendsClause != null) {
         if (!checkForImplementsDisallowedClass(implementsClause) && !checkForExtendsDisallowedClass(extendsClause)) {
@@ -9849,7 +10052,7 @@
         List<FieldElement> fieldElements = classElement.fields;
         _initialFieldElementsMap = new Map<FieldElement, INIT_STATE>();
         for (FieldElement fieldElement in fieldElements) {
-          if (!fieldElement.isSynthetic()) {
+          if (!fieldElement.isSynthetic) {
             _initialFieldElementsMap[fieldElement] = fieldElement.initializer == null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION;
           }
         }
@@ -9921,10 +10124,16 @@
     checkForExportInternalLibrary(node);
     return super.visitExportDirective(node);
   }
+  Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    FunctionType functionType = _enclosingFunction == null ? null : _enclosingFunction.type;
+    Type2 expectedReturnType = functionType == null ? DynamicTypeImpl.instance : functionType.returnType;
+    checkForReturnOfInvalidType(node.expression, expectedReturnType);
+    return super.visitExpressionFunctionBody(node);
+  }
   Object visitFieldDeclaration(FieldDeclaration node) {
-    if (!node.isStatic()) {
+    if (!node.isStatic) {
       VariableDeclarationList variables = node.fields;
-      if (variables.isConst()) {
+      if (variables.isConst) {
         _errorReporter.reportError4(CompileTimeErrorCode.CONST_INSTANCE_FIELD, variables.keyword, []);
       }
     }
@@ -9939,14 +10148,14 @@
     ExecutableElement outerFunction = _enclosingFunction;
     try {
       SimpleIdentifier identifier = node.name;
-      String methoName = "";
+      String methodName = "";
       if (identifier != null) {
-        methoName = identifier.name;
+        methodName = identifier.name;
       }
       _enclosingFunction = node.element;
-      if (node.isSetter() || node.isGetter()) {
-        checkForMismatchedAccessorTypes(node, methoName);
-        if (node.isSetter()) {
+      if (node.isSetter || node.isGetter) {
+        checkForMismatchedAccessorTypes(node, methodName);
+        if (node.isSetter) {
           FunctionExpression functionExpression = node.functionExpression;
           if (functionExpression != null) {
             checkForWrongNumberOfParametersForSetter(node.name, functionExpression.parameters);
@@ -9961,12 +10170,16 @@
     }
   }
   Object visitFunctionExpression(FunctionExpression node) {
-    ExecutableElement outerFunction = _enclosingFunction;
-    try {
-      _enclosingFunction = node.element;
+    if (node.parent is! FunctionDeclaration) {
+      ExecutableElement outerFunction = _enclosingFunction;
+      try {
+        _enclosingFunction = node.element;
+        return super.visitFunctionExpression(node);
+      } finally {
+        _enclosingFunction = outerFunction;
+      }
+    } else {
       return super.visitFunctionExpression(node);
-    } finally {
-      _enclosingFunction = outerFunction;
     }
   }
   Object visitFunctionTypeAlias(FunctionTypeAlias node) {
@@ -9994,7 +10207,7 @@
     if (type is InterfaceType) {
       InterfaceType interfaceType = type as InterfaceType;
       checkForConstOrNewWithAbstractClass(node, typeName, interfaceType);
-      if (node.isConst()) {
+      if (node.isConst) {
         checkForConstWithNonConst(node);
         checkForConstWithUndefinedConstructor(node);
         checkForConstWithTypeParameters(node);
@@ -10040,17 +10253,17 @@
       if (identifier != null) {
         methoName = identifier.name;
       }
-      if (node.isSetter() || node.isGetter()) {
+      if (node.isSetter || node.isGetter) {
         checkForMismatchedAccessorTypes(node, methoName);
         checkForConflictingInstanceGetterAndSuperclassMember(node);
       }
-      if (node.isGetter()) {
+      if (node.isGetter) {
         checkForConflictingStaticGetterAndInstanceSetter(node);
-      } else if (node.isSetter()) {
+      } else if (node.isSetter) {
         checkForWrongNumberOfParametersForSetter(node.name, node.parameters);
         checkForNonVoidReturnTypeForSetter(node.returnType);
         checkForConflictingStaticSetterAndInstanceMember(node);
-      } else if (node.isOperator()) {
+      } else if (node.isOperator) {
         checkForOptionalParameterInOperator(node);
         checkForWrongNumberOfParametersForOperator(node);
         checkForNonVoidReturnTypeForOperator(node);
@@ -10079,7 +10292,7 @@
     return super.visitPrefixedIdentifier(node);
   }
   Object visitPrefixExpression(PrefixExpression node) {
-    if (node.operator.type.isIncrementOperator()) {
+    if (node.operator.type.isIncrementOperator) {
       checkForAssignmentToFinal2(node.operand);
     }
     return super.visitPrefixExpression(node);
@@ -10176,8 +10389,8 @@
   /**
    * This verifies that the passed constructor declaration does not violate any of the error codes
    * relating to the initialization of fields in the enclosing class.
-   * @param node the {@link ConstructorDeclaration} to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @param node the [ConstructorDeclaration] to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
    * @see #initialFieldElementsMap
    * @see CompileTimeErrorCode#FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR
    * @see CompileTimeErrorCode#FINAL_INITIALIZED_MULTIPLE_TIMES
@@ -10200,12 +10413,12 @@
         if (identical(state, INIT_STATE.NOT_INIT)) {
           fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL;
         } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) {
-          if (fieldElement.isFinal() || fieldElement.isConst()) {
+          if (fieldElement.isFinal || fieldElement.isConst) {
             _errorReporter.reportError2(CompileTimeErrorCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR, formalParameter.identifier, [fieldElement.displayName]);
             foundError = true;
           }
         } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) {
-          if (fieldElement.isFinal() || fieldElement.isConst()) {
+          if (fieldElement.isFinal || fieldElement.isConst) {
             _errorReporter.reportError2(CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, formalParameter.identifier, [fieldElement.displayName]);
             foundError = true;
           }
@@ -10224,7 +10437,7 @@
           if (identical(state, INIT_STATE.NOT_INIT)) {
             fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_INITIALIZERS;
           } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) {
-            if (fieldElement.isFinal() || fieldElement.isConst()) {
+            if (fieldElement.isFinal || fieldElement.isConst) {
               _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION, fieldName, []);
               foundError = true;
             }
@@ -10243,8 +10456,8 @@
 
   /**
    * This checks the passed method declaration against override-error codes.
-   * @param node the {@link MethodDeclaration} to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @param node the [MethodDeclaration] to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
    * @see CompileTimeErrorCode#INVALID_OVERRIDE_REQUIRED
    * @see CompileTimeErrorCode#INVALID_OVERRIDE_POSITIONAL
@@ -10255,9 +10468,10 @@
    * @see StaticWarningCode#INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE
    * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE
    * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE
+   * @see StaticWarningCode#INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
    */
   bool checkForAllInvalidOverrideErrorCodes(MethodDeclaration node) {
-    if (_enclosingClass == null || node.isStatic() || node.body is NativeFunctionBody) {
+    if (_enclosingClass == null || node.isStatic || node.body is NativeFunctionBody) {
       return false;
     }
     ExecutableElement executableElement = node.element;
@@ -10265,13 +10479,13 @@
       return false;
     }
     SimpleIdentifier methodName = node.name;
-    if (methodName.isSynthetic()) {
+    if (methodName.isSynthetic) {
       return false;
     }
     String methodNameStr = methodName.name;
     ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritance(_enclosingClass, executableElement.name);
     if (overriddenExecutable == null) {
-      if (!node.isGetter() && !node.isSetter() && !node.isOperator()) {
+      if (!node.isGetter && !node.isSetter && !node.isOperator) {
         Set<ClassElement> visitedClasses = new Set<ClassElement>();
         InterfaceType superclassType = _enclosingClass.supertype;
         ClassElement superclassElement = superclassType == null ? null : superclassType.element;
@@ -10279,21 +10493,21 @@
           javaSetAdd(visitedClasses, superclassElement);
           List<FieldElement> fieldElts = superclassElement.fields;
           for (FieldElement fieldElt in fieldElts) {
-            if (fieldElt.name == methodNameStr && fieldElt.isStatic()) {
+            if (fieldElt.name == methodNameStr && fieldElt.isStatic) {
               _errorReporter.reportError2(StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, methodName, [methodNameStr, fieldElt.enclosingElement.displayName]);
               return true;
             }
           }
           List<PropertyAccessorElement> propertyAccessorElts = superclassElement.accessors;
           for (PropertyAccessorElement accessorElt in propertyAccessorElts) {
-            if (accessorElt.name == methodNameStr && accessorElt.isStatic()) {
+            if (accessorElt.name == methodNameStr && accessorElt.isStatic) {
               _errorReporter.reportError2(StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, methodName, [methodNameStr, accessorElt.enclosingElement.displayName]);
               return true;
             }
           }
           List<MethodElement> methodElements = superclassElement.methods;
           for (MethodElement methodElement in methodElements) {
-            if (methodElement.name == methodNameStr && methodElement.isStatic()) {
+            if (methodElement.name == methodNameStr && methodElement.isStatic) {
               _errorReporter.reportError2(StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, methodName, [methodNameStr, methodElement.enclosingElement.displayName]);
               return true;
             }
@@ -10337,7 +10551,7 @@
       }
     }
     if (overriddenFTReturnType != VoidTypeImpl.instance && !overridingFTReturnType.isAssignableTo(overriddenFTReturnType)) {
-      _errorReporter.reportError2(!node.isGetter() ? StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, methodName, [overridingFTReturnType.displayName, overriddenFTReturnType.displayName, overriddenExecutable.enclosingElement.displayName]);
+      _errorReporter.reportError2(!node.isGetter ? StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, methodName, [overridingFTReturnType.displayName, overriddenFTReturnType.displayName, overriddenExecutable.enclosingElement.displayName]);
       return true;
     }
     FormalParameterList formalParameterList = node.parameters;
@@ -10348,7 +10562,7 @@
     int parameterIndex = 0;
     for (int i = 0; i < overridingNormalPT.length; i++) {
       if (!overridingNormalPT[i].isAssignableTo(overriddenNormalPT[i])) {
-        _errorReporter.reportError2(!node.isSetter() ? StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE, parameterNodeList[parameterIndex], [overridingNormalPT[i].displayName, overriddenNormalPT[i].displayName, overriddenExecutable.enclosingElement.displayName]);
+        _errorReporter.reportError2(!node.isSetter ? StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE, parameterNodeList[parameterIndex], [overridingNormalPT[i].displayName, overriddenNormalPT[i].displayName, overriddenExecutable.enclosingElement.displayName]);
         return true;
       }
       parameterIndex++;
@@ -10385,13 +10599,72 @@
         }
       }
     }
-    return false;
+    bool foundError = false;
+    List<FormalParameter> formalParameters = new List<FormalParameter>();
+    List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>();
+    List<ParameterElementImpl> overriddenParameterElts = new List<ParameterElementImpl>();
+    List<ParameterElement> overriddenPEs = overriddenExecutable.parameters;
+    for (FormalParameter formalParameter in parameterNodeList) {
+      if (formalParameter.kind.isOptional) {
+        formalParameters.add(formalParameter);
+        parameterElts.add((formalParameter.element as ParameterElementImpl));
+      }
+    }
+    for (ParameterElement parameterElt in overriddenPEs) {
+      if (parameterElt.parameterKind.isOptional) {
+        overriddenParameterElts.add((parameterElt as ParameterElementImpl));
+      }
+    }
+    if (parameterElts.length > 0) {
+      if (identical(parameterElts[0].parameterKind, ParameterKind.NAMED)) {
+        for (int i = 0; i < parameterElts.length; i++) {
+          ParameterElementImpl parameterElt = parameterElts[i];
+          EvaluationResultImpl result = parameterElt.evaluationResult;
+          if (result == null || identical(result, ValidResult.RESULT_OBJECT)) {
+            continue;
+          }
+          String parameterName = parameterElt.name;
+          for (int j = 0; j < overriddenParameterElts.length; j++) {
+            ParameterElementImpl overriddenParameterElt = overriddenParameterElts[j];
+            String overriddenParameterName = overriddenParameterElt.name;
+            if (parameterName != null && parameterName == overriddenParameterName) {
+              EvaluationResultImpl overriddenResult = overriddenParameterElt.evaluationResult;
+              if (overriddenResult == null || identical(result, ValidResult.RESULT_OBJECT)) {
+                break;
+              }
+              if (!result.equalValues(overriddenResult)) {
+                _errorReporter.reportError2(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED, formalParameters[i], [overriddenExecutable.enclosingElement.displayName, overriddenExecutable.displayName, parameterName]);
+                foundError = true;
+              }
+            }
+          }
+        }
+      } else {
+        for (int i = 0; i < parameterElts.length && i < overriddenParameterElts.length; i++) {
+          ParameterElementImpl parameterElt = parameterElts[i];
+          EvaluationResultImpl result = parameterElt.evaluationResult;
+          if (result == null || identical(result, ValidResult.RESULT_OBJECT)) {
+            continue;
+          }
+          ParameterElementImpl overriddenParameterElt = overriddenParameterElts[i];
+          EvaluationResultImpl overriddenResult = overriddenParameterElt.evaluationResult;
+          if (overriddenResult == null || identical(result, ValidResult.RESULT_OBJECT)) {
+            continue;
+          }
+          if (!result.equalValues(overriddenResult)) {
+            _errorReporter.reportError2(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL, formalParameters[i], [overriddenExecutable.enclosingElement.displayName, overriddenExecutable.displayName]);
+            foundError = true;
+          }
+        }
+      }
+    }
+    return foundError;
   }
 
   /**
    * This verifies that all classes of the passed 'with' clause are valid.
    * @param node the 'with' clause to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR
    * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT
    * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER
@@ -10417,7 +10690,7 @@
   /**
    * This checks error related to the redirected constructors.
    * @param node the constructor declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#REDIRECT_TO_INVALID_RETURN_TYPE
    * @see StaticWarningCode#REDIRECT_TO_INVALID_FUNCTION_TYPE
    * @see StaticWarningCode#REDIRECT_TO_MISSING_CONSTRUCTOR
@@ -10459,15 +10732,15 @@
   /**
    * This checks that the return statement of the form <i>return e;</i> is not in a generative
    * constructor.
-   * <p>
+   *
    * This checks that return statements without expressions are not in a generative constructor and
-   * the return type is not assignable to {@code null}; that is, we don't have {@code return;} if
+   * the return type is not assignable to `null`; that is, we don't have `return;` if
    * the enclosing method has a return type.
-   * <p>
+   *
    * This checks that the return type matches the type of the declared return type in the enclosing
    * method or function.
    * @param node the return statement to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR
    * @see StaticWarningCode#RETURN_WITHOUT_VALUE
    * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
@@ -10476,7 +10749,7 @@
     FunctionType functionType = _enclosingFunction == null ? null : _enclosingFunction.type;
     Type2 expectedReturnType = functionType == null ? DynamicTypeImpl.instance : functionType.returnType;
     Expression returnExpression = node.expression;
-    bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && !((_enclosingFunction as ConstructorElement)).isFactory();
+    bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && !((_enclosingFunction as ConstructorElement)).isFactory;
     if (isGenerativeConstructor) {
       if (returnExpression == null) {
         return false;
@@ -10491,37 +10764,14 @@
       _errorReporter.reportError2(StaticWarningCode.RETURN_WITHOUT_VALUE, node, []);
       return true;
     }
-    Type2 staticReturnType = getStaticType(returnExpression);
-    if (expectedReturnType.isVoid()) {
-      if (staticReturnType.isVoid() || staticReturnType.isDynamic() || identical(staticReturnType, BottomTypeImpl.instance)) {
-        return false;
-      }
-      _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [staticReturnType.displayName, expectedReturnType.displayName, _enclosingFunction.displayName]);
-      return true;
-    }
-    bool isStaticAssignable = staticReturnType.isAssignableTo(expectedReturnType);
-    Type2 propagatedReturnType = getPropagatedType(returnExpression);
-    if (_strictMode || propagatedReturnType == null) {
-      if (isStaticAssignable) {
-        return false;
-      }
-      _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [staticReturnType.displayName, expectedReturnType.displayName, _enclosingFunction.displayName]);
-      return true;
-    } else {
-      bool isPropagatedAssignable = propagatedReturnType.isAssignableTo(expectedReturnType);
-      if (isStaticAssignable || isPropagatedAssignable) {
-        return false;
-      }
-      _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [staticReturnType.displayName, expectedReturnType.displayName, _enclosingFunction.displayName]);
-      return true;
-    }
+    return checkForReturnOfInvalidType(returnExpression, expectedReturnType);
   }
 
   /**
    * This verifies that the export namespace of the passed export directive does not export any name
    * already exported by other export directive.
    * @param node the export directive node to report problem on
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#AMBIGUOUS_EXPORT
    */
   bool checkForAmbiguousExport(ExportDirective node) {
@@ -10549,8 +10799,8 @@
 
   /**
    * This verifies that the passed argument definition test identifier is a parameter.
-   * @param node the {@link ArgumentDefinitionTest} to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @param node the [ArgumentDefinitionTest] to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#ARGUMENT_DEFINITION_TEST_NON_PARAMETER
    */
   bool checkForArgumentDefinitionTestNonParameter(ArgumentDefinitionTest node) {
@@ -10566,7 +10816,7 @@
   /**
    * This verifies that the passed arguments can be assigned to their corresponding parameters.
    * @param node the arguments to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
    */
   bool checkForArgumentTypeNotAssignable(ArgumentList argumentList) {
@@ -10583,7 +10833,7 @@
   /**
    * This verifies that the passed argument can be assigned to their corresponding parameters.
    * @param node the argument to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
    */
   bool checkForArgumentTypeNotAssignable2(Expression argument) {
@@ -10623,7 +10873,7 @@
   /**
    * This verifies that left hand side of the passed assignment expression is not final.
    * @param node the assignment expression to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#ASSIGNMENT_TO_FINAL
    */
   bool checkForAssignmentToFinal(AssignmentExpression node) {
@@ -10634,7 +10884,7 @@
   /**
    * This verifies that the passed expression is not final.
    * @param node the expression to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#ASSIGNMENT_TO_FINAL
    */
   bool checkForAssignmentToFinal2(Expression expression) {
@@ -10647,7 +10897,7 @@
     }
     if (element is VariableElement) {
       VariableElement leftVar = element as VariableElement;
-      if (leftVar.isFinal()) {
+      if (leftVar.isFinal) {
         _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_FINAL, expression, []);
         return true;
       }
@@ -10655,7 +10905,7 @@
     }
     if (element is PropertyAccessorElement) {
       PropertyAccessorElement leftAccessor = element as PropertyAccessorElement;
-      if (!leftAccessor.isSetter()) {
+      if (!leftAccessor.isSetter) {
         _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_FINAL, expression, []);
         return true;
       }
@@ -10669,8 +10919,8 @@
    * on the identifier if it is a keyword.
    * @param identifier the identifier to check to ensure that it is not a keyword
    * @param errorCode if the passed identifier is a keyword then this error code is created on the
-   * identifier, the error code will be one of{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME},{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME} or{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME}
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * identifier, the error code will be one of[CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME],[CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME] or[CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME
    * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME
    * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME
@@ -10687,7 +10937,7 @@
   /**
    * This verifies that the passed variable declaration list does not have a built-in identifier.
    * @param node the variable declaration list to check
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE
    */
   bool checkForBuiltInIdentifierAsName2(VariableDeclarationList node) {
@@ -10712,7 +10962,7 @@
    * This verifies that the given switch case is terminated with 'break', 'continue', 'return' or
    * 'throw'.
    * @param node the switch case to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED
    */
   bool checkForCaseBlockNotTerminated(SwitchCase node) {
@@ -10747,7 +10997,7 @@
    * This verifies that the switch cases in the given switch statement is terminated with 'break',
    * 'continue', 'return' or 'throw'.
    * @param node the switch statement containing the cases to be checked
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED
    */
   bool checkForCaseBlocksNotTerminated(SwitchStatement node) {
@@ -10767,7 +11017,7 @@
    * This verifies that the passed switch statement does not have a case expression with the
    * operator '==' overridden.
    * @param node the switch statement to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
    */
   bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node) {
@@ -10791,11 +11041,11 @@
    * This verifies that the passed method declaration is abstract only if the enclosing class is
    * also abstract.
    * @param node the method declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#CONCRETE_CLASS_WITH_ABSTRACT_MEMBER
    */
   bool checkForConcreteClassWithAbstractMember(MethodDeclaration node) {
-    if (node.isAbstract() && _enclosingClass != null && !_enclosingClass.isAbstract()) {
+    if (node.isAbstract && _enclosingClass != null && !_enclosingClass.isAbstract) {
       SimpleIdentifier methodName = node.name;
       _errorReporter.reportError2(StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, methodName, [methodName.name, _enclosingClass.displayName]);
       return true;
@@ -10807,7 +11057,7 @@
    * This verifies all possible conflicts of the constructor name with other constructors and
    * members of the same class.
    * @param node the constructor declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_DEFAULT
    * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_NAME
    * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD
@@ -10832,7 +11082,7 @@
         return true;
       }
     }
-    if (constructorName != null && constructorElement != null && !constructorName.isSynthetic()) {
+    if (constructorName != null && constructorElement != null && !constructorName.isSynthetic) {
       List<FieldElement> fields = classElement.fields;
       for (FieldElement field in fields) {
         if (field.name == name) {
@@ -10855,12 +11105,12 @@
    * This verifies that the superclass of the enclosing class does not declare accessible static
    * member with the same name as the passed instance getter/setter method declaration.
    * @param node the method declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER
    * @see StaticWarningCode#CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER
    */
   bool checkForConflictingInstanceGetterAndSuperclassMember(MethodDeclaration node) {
-    if (node.isStatic()) {
+    if (node.isStatic) {
       return false;
     }
     SimpleIdentifier nameNode = node.name;
@@ -10883,12 +11133,12 @@
     if (superElement == null) {
       return false;
     }
-    if (!superElement.isStatic()) {
+    if (!superElement.isStatic) {
       return false;
     }
     ClassElement superElementClass = superElement.enclosingElement as ClassElement;
     InterfaceType superElementType = superElementClass.type;
-    if (node.isGetter()) {
+    if (node.isGetter) {
       _errorReporter.reportError2(StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, nameNode, [superElementType.displayName]);
     } else {
       _errorReporter.reportError2(StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, nameNode, [superElementType.displayName]);
@@ -10900,11 +11150,11 @@
    * This verifies that the enclosing class does not have an instance member with the same name as
    * the passed static getter method declaration.
    * @param node the method declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER
    */
   bool checkForConflictingStaticGetterAndInstanceSetter(MethodDeclaration node) {
-    if (!node.isStatic()) {
+    if (!node.isStatic) {
       return false;
     }
     SimpleIdentifier nameNode = node.name;
@@ -10920,7 +11170,7 @@
     if (setter == null) {
       return false;
     }
-    if (setter.isStatic()) {
+    if (setter.isStatic) {
       return false;
     }
     ClassElement setterClass = setter.enclosingElement as ClassElement;
@@ -10933,11 +11183,11 @@
    * This verifies that the enclosing class does not have an instance member with the same name as
    * the passed static getter method declaration.
    * @param node the method declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER
    */
   bool checkForConflictingStaticSetterAndInstanceMember(MethodDeclaration node) {
-    if (!node.isStatic()) {
+    if (!node.isStatic) {
       return false;
     }
     SimpleIdentifier nameNode = node.name;
@@ -10960,7 +11210,7 @@
     if (member == null) {
       return false;
     }
-    if (member.isStatic()) {
+    if (member.isStatic) {
       return false;
     }
     ClassElement memberClass = member.enclosingElement as ClassElement;
@@ -10973,7 +11223,7 @@
    * This verifies that the passed constructor declaration is 'const' then there are no non-final
    * instance variable.
    * @param node the constructor declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
    */
   bool checkForConstConstructorWithNonFinalField(ConstructorDeclaration node) {
@@ -10993,7 +11243,7 @@
    * This verifies that the passed throw expression is not enclosed in a 'const' constructor
    * declaration.
    * @param node the throw expression expression to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_THROWS_EXCEPTION
    */
   bool checkForConstEvalThrowsException(ThrowExpression node) {
@@ -11007,11 +11257,11 @@
   /**
    * This verifies that the passed normal formal parameter is not 'const'.
    * @param node the normal formal parameter to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#CONST_FORMAL_PARAMETER
    */
   bool checkForConstFormalParameter(NormalFormalParameter node) {
-    if (node.isConst()) {
+    if (node.isConst) {
       _errorReporter.reportError2(CompileTimeErrorCode.CONST_FORMAL_PARAMETER, node, []);
       return true;
     }
@@ -11022,16 +11272,16 @@
    * This verifies that the passed instance creation expression is not being invoked on an abstract
    * class.
    * @param node the instance creation expression to evaluate
-   * @param typeName the {@link TypeName} of the {@link ConstructorName} from the{@link InstanceCreationExpression}, this is the AST node that the error is attached to
-   * @param type the type being constructed with this {@link InstanceCreationExpression}
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @param typeName the [TypeName] of the [ConstructorName] from the[InstanceCreationExpression], this is the AST node that the error is attached to
+   * @param type the type being constructed with this [InstanceCreationExpression]
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#CONST_WITH_ABSTRACT_CLASS
    * @see StaticWarningCode#NEW_WITH_ABSTRACT_CLASS
    */
   bool checkForConstOrNewWithAbstractClass(InstanceCreationExpression node, TypeName typeName, InterfaceType type) {
-    if (type.element.isAbstract()) {
+    if (type.element.isAbstract) {
       ConstructorElement element = node.element;
-      if (element != null && !element.isFactory()) {
+      if (element != null && !element.isFactory) {
         if (identical(((node.keyword as sc.KeywordToken)).keyword, sc.Keyword.CONST)) {
           _errorReporter.reportError2(StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName, []);
         } else {
@@ -11046,15 +11296,15 @@
   /**
    * This verifies that the passed 'const' instance creation expression is not being invoked on a
    * constructor that is not 'const'.
-   * <p>
+   *
    * This method assumes that the instance creation was tested to be 'const' before being called.
    * @param node the instance creation expression to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#CONST_WITH_NON_CONST
    */
   bool checkForConstWithNonConst(InstanceCreationExpression node) {
     ConstructorElement constructorElement = node.element;
-    if (constructorElement != null && !constructorElement.isConst()) {
+    if (constructorElement != null && !constructorElement.isConst) {
       _errorReporter.reportError2(CompileTimeErrorCode.CONST_WITH_NON_CONST, node, []);
       return true;
     }
@@ -11064,10 +11314,10 @@
   /**
    * This verifies that the passed 'const' instance creation expression does not reference any type
    * parameters.
-   * <p>
+   *
    * This method assumes that the instance creation was tested to be 'const' before being called.
    * @param node the instance creation expression to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS
    */
   bool checkForConstWithTypeParameters(InstanceCreationExpression node) {
@@ -11082,7 +11332,7 @@
   /**
    * This verifies that the passed type name does not reference any type parameters.
    * @param typeName the type name to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS
    */
   bool checkForConstWithTypeParameters2(TypeName typeName) {
@@ -11110,10 +11360,10 @@
   /**
    * This verifies that if the passed 'const' instance creation expression is being invoked on the
    * resolved constructor.
-   * <p>
+   *
    * This method assumes that the instance creation was tested to be 'const' before being called.
    * @param node the instance creation expression to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR
    * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT
    */
@@ -11142,7 +11392,7 @@
   /**
    * This verifies that there are no default parameters in the passed function type alias.
    * @param node the function type alias to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS
    */
   bool checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) {
@@ -11164,7 +11414,7 @@
   /**
    * This verifies the passed import has unique name among other exported libraries.
    * @param node the export directive to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#EXPORT_DUPLICATED_LIBRARY_NAME
    */
   bool checkForExportDuplicateLibraryName(ExportDirective node) {
@@ -11194,7 +11444,7 @@
    * Check that if the visiting library is not system, then any passed library should not be SDK
    * internal library.
    * @param node the export directive to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#EXPORT_INTERNAL_LIBRARY
    */
   bool checkForExportInternalLibrary(ExportDirective node) {
@@ -11212,7 +11462,7 @@
     if (sdkLibrary == null) {
       return false;
     }
-    if (!sdkLibrary.isInternal()) {
+    if (!sdkLibrary.isInternal) {
       return false;
     }
     _errorReporter.reportError2(CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, node, [node.uri]);
@@ -11222,7 +11472,7 @@
   /**
    * This verifies that the passed extends clause does not extend classes such as num or String.
    * @param node the extends clause to test
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
    */
   bool checkForExtendsDisallowedClass(ExtendsClause extendsClause) {
@@ -11236,14 +11486,14 @@
    * This verifies that the passed type name does not extend or implement classes such as 'num' or
    * 'String'.
    * @param node the type name to test
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see #checkForExtendsDisallowedClass(ExtendsClause)
    * @see #checkForImplementsDisallowedClass(ImplementsClause)
    * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
    * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS
    */
   bool checkForExtendsOrImplementsDisallowedClass(TypeName typeName, ErrorCode errorCode) {
-    if (typeName.isSynthetic()) {
+    if (typeName.isSynthetic) {
       return false;
     }
     Type2 superType = typeName.type;
@@ -11270,7 +11520,7 @@
    * This verifies that the passed constructor field initializer has compatible field and
    * initializer expression types.
    * @param node the constructor field initializer to test
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
    * @see StaticWarningCode#FIELD_INITIALIZER_NOT_ASSIGNABLE
    */
@@ -11314,7 +11564,7 @@
   /**
    * This verifies that the passed field formal parameter is in a constructor declaration.
    * @param node the field formal parameter to test
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
    */
   bool checkForFieldInitializingFormalRedirectingConstructor(FieldFormalParameter node) {
@@ -11339,9 +11589,9 @@
   /**
    * This verifies that final fields that are declared, without any constructors in the enclosing
    * class, are initialized. Cases in which there is at least one constructor are handled at the end
-   * of {@link #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration)}.
+   * of [checkForAllFinalInitializedErrorCodes].
    * @param node the class declaration to test
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#FINAL_NOT_INITIALIZED
    */
   bool checkForFinalNotInitialized(ClassDeclaration node) {
@@ -11363,14 +11613,14 @@
 
   /**
    * This verifies that the passed variable declaration list has only initialized variables if the
-   * list is final or const. This method is called by{@link #checkForFinalNotInitialized(ClassDeclaration)},{@link #visitTopLevelVariableDeclaration(TopLevelVariableDeclaration)} and{@link #visitVariableDeclarationStatement(VariableDeclarationStatement)}.
+   * list is final or const. This method is called by[checkForFinalNotInitialized],[visitTopLevelVariableDeclaration] and[visitVariableDeclarationStatement].
    * @param node the class declaration to test
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#FINAL_NOT_INITIALIZED
    */
   bool checkForFinalNotInitialized2(VariableDeclarationList node) {
     bool foundError = false;
-    if (!node.isSynthetic() && (node.isConst() || node.isFinal())) {
+    if (!node.isSynthetic && (node.isConst || node.isFinal)) {
       NodeList<VariableDeclaration> variables = node.variables;
       for (VariableDeclaration variable in variables) {
         if (variable.initializer == null) {
@@ -11386,7 +11636,7 @@
    * This verifies that the passed implements clause does not implement classes such as 'num' or
    * 'String'.
    * @param node the implements clause to test
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS
    */
   bool checkForImplementsDisallowedClass(ImplementsClause implementsClause) {
@@ -11404,7 +11654,7 @@
    * This verifies that if the passed identifier is part of constructor initializer, then it does
    * not reference implicitly 'this' expression.
    * @param node the simple identifier to test
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#IMPLICIT_THIS_REFERENCE_IN_INITIALIZER
    */
   bool checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) {
@@ -11416,7 +11666,7 @@
       return false;
     }
     ExecutableElement executableElement = element as ExecutableElement;
-    if (executableElement.isStatic()) {
+    if (executableElement.isStatic) {
       return false;
     }
     Element enclosingElement = element.enclosingElement;
@@ -11451,7 +11701,7 @@
   /**
    * This verifies the passed import has unique name among other imported libraries.
    * @param node the import directive to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#IMPORT_DUPLICATED_LIBRARY_NAME
    */
   bool checkForImportDuplicateLibraryName(ImportDirective node) {
@@ -11481,7 +11731,7 @@
    * Check that if the visiting library is not system, then any passed library should not be SDK
    * internal library.
    * @param node the import directive to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#IMPORT_INTERNAL_LIBRARY
    */
   bool checkForImportInternalLibrary(ImportDirective node) {
@@ -11499,7 +11749,7 @@
     if (sdkLibrary == null) {
       return false;
     }
-    if (!sdkLibrary.isInternal()) {
+    if (!sdkLibrary.isInternal) {
       return false;
     }
     _errorReporter.reportError2(CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, node, [node.uri]);
@@ -11509,7 +11759,7 @@
   /**
    * This verifies that the passed switch statement case expressions all have the same type.
    * @param node the switch statement to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#INCONSISTENT_CASE_EXPRESSION_TYPES
    */
   bool checkForInconsistentCaseExpressionTypes(SwitchStatement node) {
@@ -11537,7 +11787,7 @@
   /**
    * For each class declaration, this method is called which verifies that all inherited members are
    * inherited consistently.
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticTypeWarningCode#INCONSISTENT_METHOD_INHERITANCE
    */
   bool checkForInconsistentMethodInheritance() {
@@ -11556,7 +11806,7 @@
    * Given an assignment using a compound assignment operator, this verifies that the given
    * assignment is valid.
    * @param node the assignment expression being tested
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
    */
   bool checkForInvalidAssignment(AssignmentExpression node) {
@@ -11585,7 +11835,7 @@
    * This verifies that the passed left hand side and right hand side represent a valid assignment.
    * @param lhs the left hand side expression
    * @param rhs the right hand side expression
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
    */
   bool checkForInvalidAssignment2(Expression lhs, Expression rhs) {
@@ -11615,7 +11865,7 @@
   /**
    * This verifies that the usage of the passed 'this' is valid.
    * @param node the 'this' expression to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#INVALID_REFERENCE_TO_THIS
    */
   bool checkForInvalidReferenceToThis(ThisExpression node) {
@@ -11628,8 +11878,8 @@
 
   /**
    * Checks to ensure that first type argument to a map literal must be the 'String' type.
-   * @param arguments a non-{@code null}, non-empty {@link TypeName} node list from the respective{@link MapLiteral}
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @param arguments a non-`null`, non-empty [TypeName] node list from the respective[MapLiteral]
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_FOR_KEY
    */
   bool checkForInvalidTypeArgumentForKey(NodeList<TypeName> arguments) {
@@ -11643,11 +11893,11 @@
   }
 
   /**
-   * Checks to ensure that the passed {@link ListLiteral} or {@link MapLiteral} does not have a type
+   * Checks to ensure that the passed [ListLiteral] or [MapLiteral] does not have a type
    * parameter as a type argument.
-   * @param arguments a non-{@code null}, non-empty {@link TypeName} node list from the respective{@link ListLiteral} or {@link MapLiteral}
-   * @param errorCode either {@link CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_LIST} or{@link CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_MAP}
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @param arguments a non-`null`, non-empty [TypeName] node list from the respective[ListLiteral] or [MapLiteral]
+   * @param errorCode either [CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or[CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_MAP]
+   * @return `true` if and only if an error code is generated on the passed node
    */
   bool checkForInvalidTypeArgumentInConstTypedLiteral(NodeList<TypeName> arguments, ErrorCode errorCode) {
     bool foundError = false;
@@ -11661,9 +11911,9 @@
   }
 
   /**
-   * This verifies that the {@link #enclosingClass} does not define members with the same name as
+   * This verifies that the [enclosingClass] does not define members with the same name as
    * the enclosing class.
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#MEMBER_WITH_CLASS_NAME
    */
   bool checkForMemberWithClassName() {
@@ -11702,10 +11952,10 @@
     }
     Type2 getterType = null;
     Type2 setterType = null;
-    if (propertyAccessorElement.isGetter()) {
+    if (propertyAccessorElement.isGetter) {
       getterType = getGetterType(propertyAccessorElement);
       setterType = getSetterType(counterpartAccessor);
-    } else if (propertyAccessorElement.isSetter()) {
+    } else if (propertyAccessorElement.isSetter) {
       setterType = getSetterType(propertyAccessorElement);
       counterpartAccessor = propertyAccessorElement.correspondingGetter;
       getterType = getGetterType(counterpartAccessor);
@@ -11719,12 +11969,12 @@
    * This verifies that the passed mixin does not have an explicitly declared constructor.
    * @param mixinName the node to report problem on
    * @param mixinElement the mixing to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR
    */
   bool checkForMixinDeclaresConstructor(TypeName mixinName, ClassElement mixinElement) {
     for (ConstructorElement constructor in mixinElement.constructors) {
-      if (!constructor.isSynthetic() && !constructor.isFactory()) {
+      if (!constructor.isSynthetic && !constructor.isFactory) {
         _errorReporter.reportError2(CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, mixinName, [mixinElement.name]);
         return true;
       }
@@ -11736,13 +11986,13 @@
    * This verifies that the passed mixin has the 'Object' superclass.
    * @param mixinName the node to report problem on
    * @param mixinElement the mixing to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT
    */
   bool checkForMixinInheritsNotFromObject(TypeName mixinName, ClassElement mixinElement) {
     InterfaceType mixinSupertype = mixinElement.supertype;
     if (mixinSupertype != null) {
-      if (!mixinSupertype.isObject() || !mixinElement.isTypedef() && mixinElement.mixins.length != 0) {
+      if (!mixinSupertype.isObject || !mixinElement.isTypedef && mixinElement.mixins.length != 0) {
         _errorReporter.reportError2(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, mixinName, [mixinElement.name]);
         return true;
       }
@@ -11754,7 +12004,7 @@
    * This verifies that the passed mixin does not reference 'super'.
    * @param mixinName the node to report problem on
    * @param mixinElement the mixing to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER
    */
   bool checkForMixinReferencesSuper(TypeName mixinName, ClassElement mixinElement) {
@@ -11767,7 +12017,7 @@
   /**
    * This verifies that the passed constructor has at most one 'super' initializer.
    * @param node the constructor declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#MULTIPLE_SUPER_INITIALIZERS
    */
   bool checkForMultipleSuperInitializers(ConstructorDeclaration node) {
@@ -11786,7 +12036,7 @@
   /**
    * Checks to ensure that native function bodies can only in SDK code.
    * @param node the native function body to test
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see ParserErrorCode#NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
    */
   bool checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) {
@@ -11799,10 +12049,10 @@
 
   /**
    * This verifies that the passed 'new' instance creation expression invokes existing constructor.
-   * <p>
+   *
    * This method assumes that the instance creation was tested to be 'new' before being called.
    * @param node the instance creation expression to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#NEW_WITH_UNDEFINED_CONSTRUCTOR
    */
   bool checkForNewWithUndefinedConstructor(InstanceCreationExpression node) {
@@ -11828,10 +12078,34 @@
   }
 
   /**
+   * This checks that passed if the passed class declaration implicitly calls default constructor of
+   * its superclass, there should be such default constructor - implicit or explicit.
+   * @param node the [ClassDeclaration] to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
+   */
+  bool checkForNoDefaultSuperConstructorImplicit(ClassDeclaration node) {
+    List<ConstructorElement> constructors = _enclosingClass.constructors;
+    if (!constructors[0].isSynthetic) {
+      return false;
+    }
+    InterfaceType superType = _enclosingClass.supertype;
+    if (superType == null) {
+      return false;
+    }
+    ClassElement superClass = superType.element;
+    if (superClass.hasDefaultConstructor()) {
+      return false;
+    }
+    _errorReporter.reportError2(StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, node.name, [superType.displayName]);
+    return true;
+  }
+
+  /**
    * This checks that passed class declaration overrides all members required by its superclasses
    * and interfaces.
-   * @param node the {@link ClassDeclaration} to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @param node the [ClassDeclaration] to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
    * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO
    * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE
@@ -11839,7 +12113,7 @@
    * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS
    */
   bool checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration node) {
-    if (_enclosingClass.isAbstract()) {
+    if (_enclosingClass.isAbstract) {
       return false;
     }
     Set<ExecutableElement> missingOverrides = new Set<ExecutableElement>();
@@ -11858,7 +12132,7 @@
       ExecutableElement executableElt = entry.getValue();
       if (executableElt is MethodElement) {
         MethodElement methodElt = executableElt as MethodElement;
-        if (methodElt.isAbstract()) {
+        if (methodElt.isAbstract) {
           String methodName = entry.getKey();
           if (!methodsInEnclosingClass.contains(methodName)) {
             javaSetAdd(missingOverrides, executableElt);
@@ -11866,7 +12140,7 @@
         }
       } else if (executableElt is PropertyAccessorElement) {
         PropertyAccessorElement propertyAccessorElt = executableElt as PropertyAccessorElement;
-        if (propertyAccessorElt.isAbstract()) {
+        if (propertyAccessorElt.isAbstract) {
           String accessorName = entry.getKey();
           if (!accessorsInEnclosingClass.contains(accessorName)) {
             javaSetAdd(missingOverrides, executableElt);
@@ -11879,9 +12153,9 @@
       ExecutableElement executableElt = entry.getValue();
       ExecutableElement elt = membersInheritedFromSuperclasses[executableElt.name];
       if (elt != null) {
-        if (elt is MethodElement && !((elt as MethodElement)).isAbstract()) {
+        if (elt is MethodElement && !((elt as MethodElement)).isAbstract) {
           continue;
-        } else if (elt is PropertyAccessorElement && !((elt as PropertyAccessorElement)).isAbstract()) {
+        } else if (elt is PropertyAccessorElement && !((elt as PropertyAccessorElement)).isAbstract) {
           continue;
         }
       }
@@ -11908,7 +12182,7 @@
     for (int i = 0; i < stringTypeArray.length; i++) {
       stringTypeArray[i] = StringUtilities.EMPTY;
       if (missingOverridesArray[i] is PropertyAccessorElement) {
-        stringTypeArray[i] = ((missingOverridesArray[i] as PropertyAccessorElement)).isGetter() ? GET : SET;
+        stringTypeArray[i] = ((missingOverridesArray[i] as PropertyAccessorElement)).isGetter ? GET : SET;
       }
     }
     AnalysisErrorWithProperties analysisError;
@@ -11932,7 +12206,7 @@
    * Checks to ensure that the expressions that need to be of type bool, are. Otherwise an error is
    * reported on the expression.
    * @param condition the conditional expression to test
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticTypeWarningCode#NON_BOOL_CONDITION
    */
   bool checkForNonBoolCondition(Expression condition) {
@@ -11947,7 +12221,7 @@
   /**
    * This verifies that the passed assert statement has either a 'bool' or '() -> bool' input.
    * @param node the assert statement to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticTypeWarningCode#NON_BOOL_EXPRESSION
    */
   bool checkForNonBoolExpression(AssertStatement node) {
@@ -11970,13 +12244,13 @@
 
   /**
    * This verifies the passed map literal either:
-   * <ul>
-   * <li>has {@code const modifier}</li>
-   * <li>has explicit type arguments</li>
-   * <li>is not start of the statement</li>
-   * <ul>
+   *
+   * * has `const modifier`
+   * * has explicit type arguments
+   * * is not start of the statement
+   *
    * @param node the map literal to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#NON_CONST_MAP_AS_EXPRESSION_STATEMENT
    */
   bool checkForNonConstMapAsExpressionStatement(MapLiteral node) {
@@ -11998,10 +12272,10 @@
   }
 
   /**
-   * This verifies the passed method declaration of operator {@code \[\]=}, has {@code void} return
+   * This verifies the passed method declaration of operator `\[\]=`, has `void` return
    * type.
    * @param node the method declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#NON_VOID_RETURN_FOR_OPERATOR
    */
   bool checkForNonVoidReturnTypeForOperator(MethodDeclaration node) {
@@ -12012,7 +12286,7 @@
     TypeName typeName = node.returnType;
     if (typeName != null) {
       Type2 type = typeName.type;
-      if (type != null && !type.isVoid()) {
+      if (type != null && !type.isVoid) {
         _errorReporter.reportError2(StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, typeName, []);
       }
     }
@@ -12020,15 +12294,15 @@
   }
 
   /**
-   * This verifies the passed setter has no return type or the {@code void} return type.
+   * This verifies the passed setter has no return type or the `void` return type.
    * @param typeName the type name to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#NON_VOID_RETURN_FOR_SETTER
    */
   bool checkForNonVoidReturnTypeForSetter(TypeName typeName) {
     if (typeName != null) {
       Type2 type = typeName.type;
-      if (type != null && !type.isVoid()) {
+      if (type != null && !type.isVoid) {
         _errorReporter.reportError2(StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, typeName, []);
       }
     }
@@ -12037,11 +12311,11 @@
 
   /**
    * This verifies the passed operator-method declaration, does not have an optional parameter.
-   * <p>
+   *
    * This method assumes that the method declaration was tested to be an operator declaration before
    * being called.
    * @param node the method declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#OPTIONAL_PARAMETER_IN_OPERATOR
    */
   bool checkForOptionalParameterInOperator(MethodDeclaration node) {
@@ -12052,7 +12326,7 @@
     bool foundError = false;
     NodeList<FormalParameter> formalParameters = parameterList.parameters;
     for (FormalParameter formalParameter in formalParameters) {
-      if (formalParameter.kind.isOptional()) {
+      if (formalParameter.kind.isOptional) {
         _errorReporter.reportError2(CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, formalParameter, []);
         foundError = true;
       }
@@ -12063,7 +12337,7 @@
   /**
    * This checks for named optional parameters that begin with '_'.
    * @param node the default formal parameter to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#PRIVATE_OPTIONAL_PARAMETER
    */
   bool checkForPrivateOptionalParameter(DefaultFormalParameter node) {
@@ -12071,7 +12345,7 @@
     if (separator != null && separator.lexeme == ":") {
       NormalFormalParameter parameter = node.parameter;
       SimpleIdentifier name = parameter.identifier;
-      if (!name.isSynthetic() && name.name.startsWith("_")) {
+      if (!name.isSynthetic && name.name.startsWith("_")) {
         _errorReporter.reportError2(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, node, []);
         return true;
       }
@@ -12083,7 +12357,7 @@
    * This checks if the passed constructor declaration is the redirecting generative constructor and
    * references itself directly or indirectly.
    * @param node the constructor declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#RECURSIVE_CONSTRUCTOR_REDIRECT
    */
   bool checkForRecursiveConstructorRedirect(ConstructorDeclaration node) {
@@ -12107,7 +12381,7 @@
    * This checks if the passed constructor declaration has redirected constructor and references
    * itself directly or indirectly.
    * @param node the constructor declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#RECURSIVE_FACTORY_REDIRECT
    */
   bool checkForRecursiveFactoryRedirect(ConstructorDeclaration node) {
@@ -12127,7 +12401,7 @@
    * This checks the class declaration is not a superinterface to itself.
    * @param classElt the class element to test
    * @param list a list containing the potentially cyclic implements path
-   * @return {@code true} if and only if an error code is generated on the passed element
+   * @return `true` if and only if an error code is generated on the passed element
    * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE
    * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS
    * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS
@@ -12166,7 +12440,7 @@
     }
     List<ClassElement> interfaceElements;
     List<InterfaceType> interfaceTypes = classElt.interfaces;
-    if (supertype != null && !supertype.isObject()) {
+    if (supertype != null && !supertype.isObject) {
       interfaceElements = new List<ClassElement>(interfaceTypes.length + 1);
       interfaceElements[0] = supertype.element;
       for (int i = 0; i < interfaceTypes.length; i++) {
@@ -12191,7 +12465,7 @@
    * This checks the passed constructor declaration has a valid combination of redirected
    * constructor invocation(s), super constructor invocations and field initializers.
    * @param node the constructor declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS
    * @see CompileTimeErrorCode#SUPER_IN_REDIRECTING_CONSTRUCTOR
    * @see CompileTimeErrorCode#FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR
@@ -12227,7 +12501,7 @@
    * This checks if the passed constructor declaration has redirected constructor and references
    * itself directly or indirectly. TODO(scheglov)
    * @param node the constructor declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#REDIRECT_TO_NON_CONST_CONSTRUCTOR
    */
   bool checkForRedirectToNonConstConstructor(ConstructorDeclaration node) {
@@ -12239,14 +12513,14 @@
     if (element == null) {
       return false;
     }
-    if (!element.isConst()) {
+    if (!element.isConst) {
       return false;
     }
     ConstructorElement redirectedConstructor = element.redirectedConstructor;
     if (redirectedConstructor == null) {
       return false;
     }
-    if (redirectedConstructor.isConst()) {
+    if (redirectedConstructor.isConst) {
       return false;
     }
     _errorReporter.reportError2(CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, redirectedConstructorNode, []);
@@ -12257,7 +12531,7 @@
    * This checks if the passed identifier is banned because it is part of the variable declaration
    * with the same name.
    * @param node the identifier to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER
    */
   bool checkForReferenceToDeclaredVariableInInitializer(SimpleIdentifier node) {
@@ -12303,7 +12577,7 @@
   /**
    * This checks that the rethrow is inside of a catch clause.
    * @param node the rethrow expression to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#RETHROW_OUTSIDE_CATCH
    */
   bool checkForRethrowOutsideCatch(RethrowExpression node) {
@@ -12315,11 +12589,48 @@
   }
 
   /**
+   * This checks that a type mis-match between the return type and the expressed return type by the
+   * enclosing method or function.
+   *
+   * This method is called both by [checkForAllReturnStatementErrorCodes]and [visitExpressionFunctionBody].
+   * @param returnExpression the returned expression to evaluate
+   * @param expectedReturnType the expressed return type by the enclosing method or function
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
+   */
+  bool checkForReturnOfInvalidType(Expression returnExpression, Type2 expectedReturnType) {
+    Type2 staticReturnType = getStaticType(returnExpression);
+    if (expectedReturnType.isVoid) {
+      if (staticReturnType.isVoid || staticReturnType.isDynamic || identical(staticReturnType, BottomTypeImpl.instance)) {
+        return false;
+      }
+      _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [staticReturnType.displayName, expectedReturnType.displayName, _enclosingFunction.displayName]);
+      return true;
+    }
+    bool isStaticAssignable = staticReturnType.isAssignableTo(expectedReturnType);
+    Type2 propagatedReturnType = getPropagatedType(returnExpression);
+    if (_strictMode || propagatedReturnType == null) {
+      if (isStaticAssignable) {
+        return false;
+      }
+      _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [staticReturnType.displayName, expectedReturnType.displayName, _enclosingFunction.displayName]);
+      return true;
+    } else {
+      bool isPropagatedAssignable = propagatedReturnType.isAssignableTo(expectedReturnType);
+      if (isStaticAssignable || isPropagatedAssignable) {
+        return false;
+      }
+      _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [staticReturnType.displayName, expectedReturnType.displayName, _enclosingFunction.displayName]);
+      return true;
+    }
+  }
+
+  /**
    * This checks that if the given "target" is the type reference then the "name" is not the
    * reference to a instance member.
    * @param target the target of the name access to evaluate
    * @param name the accessed name to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER
    */
   bool checkForStaticAccessToInstanceMember(Expression target, SimpleIdentifier name2) {
@@ -12328,7 +12639,7 @@
       return false;
     }
     ExecutableElement memberElement = element as ExecutableElement;
-    if (memberElement.isStatic()) {
+    if (memberElement.isStatic) {
       return false;
     }
     if (!isTypeReference(target)) {
@@ -12342,7 +12653,7 @@
    * This checks that the type of the passed 'switch' expression is assignable to the type of the
    * 'case' members.
    * @param node the 'switch' statement to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#SWITCH_EXPRESSION_NOT_ASSIGNABLE
    */
   bool checkForSwitchExpressionNotAssignable(SwitchStatement node) {
@@ -12373,9 +12684,9 @@
    * their bounds as specified by the class element where the constructor \[that is being invoked\] is
    * declared.
    * @param node the instance creation expression to evaluate
-   * @param typeName the {@link TypeName} of the {@link ConstructorName} from the{@link InstanceCreationExpression}, this is the AST node that the error is attached to
-   * @param constructorElement the {@link ConstructorElement} from the instance creation expression
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @param typeName the [TypeName] of the [ConstructorName] from the[InstanceCreationExpression], this is the AST node that the error is attached to
+   * @param constructorElement the [ConstructorElement] from the instance creation expression
+   * @return `true` if and only if an error code is generated on the passed node
    * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
    */
   bool checkForTypeArgumentNotMatchingBounds(InstanceCreationExpression node, ConstructorElement constructorElement, TypeName typeName) {
@@ -12403,9 +12714,10 @@
    * invocation nor a redirecting constructor invocation, that the superclass has a default
    * generative constructor.
    * @param node the constructor declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT
    * @see CompileTimeErrorCode#NON_GENERATIVE_CONSTRUCTOR
+   * @see StaticWarningCode#NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT
    */
   bool checkForUndefinedConstructorInInitializerImplicit(ConstructorDeclaration node) {
     if (node.factoryKeyword != null) {
@@ -12424,12 +12736,23 @@
       return false;
     }
     ClassElement superElement = superType.element;
-    ConstructorElement superDefaultConstructor = superElement.unnamedConstructor;
-    if (superDefaultConstructor != null) {
-      if (superDefaultConstructor.isFactory()) {
-        _errorReporter.reportError2(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.returnType, [superDefaultConstructor]);
+    ConstructorElement superUnnamedConstructor = superElement.unnamedConstructor;
+    if (superUnnamedConstructor != null) {
+      if (superUnnamedConstructor.isFactory) {
+        _errorReporter.reportError2(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.returnType, [superUnnamedConstructor]);
         return true;
       }
+      if (!superUnnamedConstructor.isDefaultConstructor) {
+        int offset;
+        int length;
+        {
+          Identifier returnType = node.returnType;
+          SimpleIdentifier name = node.name;
+          offset = returnType.offset;
+          length = (name != null ? name.end : returnType.end) - offset;
+        }
+        _errorReporter.reportError3(StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, offset, length, [superType.displayName]);
+      }
       return false;
     }
     _errorReporter.reportError2(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node.returnType, [superElement.name]);
@@ -12438,11 +12761,11 @@
 
   /**
    * This verifies the passed operator-method declaration, has correct number of parameters.
-   * <p>
+   *
    * This method assumes that the method declaration was tested to be an operator declaration before
    * being called.
    * @param node the method declaration to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
    */
   bool checkForWrongNumberOfParametersForOperator(MethodDeclaration node) {
@@ -12477,11 +12800,11 @@
 
   /**
    * This verifies if the passed setter parameter list have only one parameter.
-   * <p>
+   *
    * This method assumes that the method declaration was tested to be a setter before being called.
    * @param setterName the name of the setter to report problems on
    * @param parameterList the parameter list to evaluate
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER
    */
   bool checkForWrongNumberOfParametersForSetter(SimpleIdentifier setterName, FormalParameterList parameterList) {
@@ -12561,7 +12884,7 @@
   }
 
   /**
-   * Return the variable element represented by the given expression, or {@code null} if there is no
+   * Return the variable element represented by the given expression, or `null` if there is no
    * such element.
    * @param expression the expression whose element is to be returned
    * @return the variable element represented by the expression
@@ -12577,7 +12900,7 @@
   }
 
   /**
-   * @return {@code true} if the given constructor redirects to itself, directly or indirectly
+   * @return `true` if the given constructor redirects to itself, directly or indirectly
    */
   bool hasRedirectingFactoryConstructorCycle(ConstructorElement element) {
     Set<ConstructorElement> constructors = new Set<ConstructorElement>();
@@ -12597,7 +12920,7 @@
 
   /**
    * @param node the 'this' expression to analyze
-   * @return {@code true} if the given 'this' expression is in the valid context
+   * @return `true` if the given 'this' expression is in the valid context
    */
   bool isThisInValidContext(ThisExpression node) {
     for (ASTNode n = node; n != null; n = n.parent) {
@@ -12613,7 +12936,7 @@
       }
       if (n is MethodDeclaration) {
         MethodDeclaration method = n as MethodDeclaration;
-        return !method.isStatic();
+        return !method.isStatic;
       }
     }
     return false;
@@ -12644,7 +12967,7 @@
   String toString() => name;
 }
 /**
- * Instances of the class {@code PubVerifier} traverse an AST structure looking for deviations from
+ * Instances of the class `PubVerifier` traverse an AST structure looking for deviations from
  * pub best practices.
  */
 class PubVerifier extends RecursiveASTVisitor<Object> {
@@ -12671,9 +12994,9 @@
    * This verifies that the passed file import directive is not contained in a source inside a
    * package "lib" directory hierarchy referencing a source outside that package "lib" directory
    * hierarchy.
-   * @param uriLiteral the import URL (not {@code null})
-   * @param path the file path being verified (not {@code null})
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @param uriLiteral the import URL (not `null`)
+   * @param path the file path being verified (not `null`)
+   * @return `true` if and only if an error code is generated on the passed node
    * @see PubSuggestionCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE
    */
   bool checkForFileImportInsideLibReferencesFileOutside(StringLiteral uriLiteral, String path) {
@@ -12683,7 +13006,7 @@
       int pathIndex = 0;
       int fullNameIndex = fullName.length;
       while (pathIndex < path.length && JavaString.startsWithBefore(path, "../", pathIndex)) {
-        fullNameIndex = fullName.lastIndexOf('/', fullNameIndex);
+        fullNameIndex = JavaString.lastIndexOf(fullName, '/', fullNameIndex);
         if (fullNameIndex < 4) {
           return false;
         }
@@ -12705,9 +13028,9 @@
    * This verifies that the passed file import directive is not contained in a source outside a
    * package "lib" directory hierarchy referencing a source inside that package "lib" directory
    * hierarchy.
-   * @param uriLiteral the import URL (not {@code null})
-   * @param path the file path being verified (not {@code null})
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @param uriLiteral the import URL (not `null`)
+   * @param path the file path being verified (not `null`)
+   * @return `true` if and only if an error code is generated on the passed node
    * @see PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE
    */
   bool checkForFileImportOutsideLibReferencesFileInside(StringLiteral uriLiteral, String path) {
@@ -12721,7 +13044,7 @@
       if (checkForFileImportOutsideLibReferencesFileInside2(uriLiteral, path, pathIndex + 1)) {
         return true;
       }
-      pathIndex = path.indexOf("/lib/", pathIndex + 4);
+      pathIndex = JavaString.indexOf(path, "/lib/", pathIndex + 4);
     }
     return false;
   }
@@ -12744,9 +13067,9 @@
 
   /**
    * This verifies that the passed package import directive does not contain ".."
-   * @param uriLiteral the import URL (not {@code null})
-   * @param path the path to be validated (not {@code null})
-   * @return {@code true} if and only if an error code is generated on the passed node
+   * @param uriLiteral the import URL (not `null`)
+   * @param path the path to be validated (not `null`)
+   * @return `true` if and only if an error code is generated on the passed node
    * @see PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
    */
   bool checkForPackageImportContainsDotDot(StringLiteral uriLiteral, String path) {
@@ -12759,8 +13082,8 @@
 
   /**
    * Answer the source associated with the compilation unit containing the given AST node.
-   * @param node the node (not {@code null})
-   * @return the source or {@code null} if it could not be determined
+   * @param node the node (not `null`)
+   * @return the source or `null` if it could not be determined
    */
   Source getSource(ASTNode node) {
     Source source = null;
@@ -12775,9 +13098,9 @@
   }
 
   /**
-   * Answer the full name of the given source. The returned value will have all{@link File#separatorChar} replace by '/'.
+   * Answer the full name of the given source. The returned value will have all[File#separatorChar] replace by '/'.
    * @param source the source
-   * @return the full name or {@code null} if it could not be determined
+   * @return the full name or `null` if it could not be determined
    */
   String getSourceFullName(Source source) {
     if (source != null) {
@@ -12790,7 +13113,7 @@
   }
 }
 /**
- * The enumeration {@code ResolverErrorCode} defines the error codes used for errors detected by the
+ * The enumeration `ResolverErrorCode` defines the error codes used for errors detected by the
  * resolver. The convention for this class is for the name of the error code to indicate the problem
  * that caused the error to be generated and for the error message to explain what is wrong and,
  * when appropriate, how the problem can be corrected.
diff --git a/pkg/analyzer_experimental/lib/src/generated/scanner.dart b/pkg/analyzer_experimental/lib/src/generated/scanner.dart
index 7c3c523..24464e6 100644
--- a/pkg/analyzer_experimental/lib/src/generated/scanner.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/scanner.dart
@@ -8,7 +8,7 @@
 import 'error.dart';
 import 'instrumentation.dart';
 /**
- * Instances of the abstract class {@code KeywordState} represent a state in a state machine used to
+ * Instances of the abstract class `KeywordState` represent a state in a state machine used to
  * scan keywords.
  * @coverage dart.engine.parser
  */
@@ -87,12 +87,12 @@
 
   /**
    * 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.)
+   * into the array is the offset from the character `'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
+   * The keyword that is recognized by this state, or `null` if this state is not a terminal
    * state.
    */
   Keyword _keyword2;
@@ -109,21 +109,21 @@
   }
 
   /**
-   * Return the keyword that was recognized by this state, or {@code null} if this state does not
+   * Return the keyword that was recognized by this state, or `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.
+   * Return the state that follows this state on a transition of the given character, or`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];
 }
 /**
- * The enumeration {@code ScannerErrorCode} defines the error codes used for errors detected by the
+ * The enumeration `ScannerErrorCode` defines the error codes used for errors detected by the
  * scanner.
  * @coverage dart.engine.parser
  */
@@ -162,7 +162,7 @@
   String toString() => name;
 }
 /**
- * Instances of the class {@code TokenWithComment} represent a string token that is preceded by
+ * Instances of the class `TokenWithComment` represent a string token that is preceded by
  * comments.
  * @coverage dart.engine.parser
  */
@@ -186,7 +186,7 @@
   Token get precedingComments => _precedingComment;
 }
 /**
- * The enumeration {@code Keyword} defines the keywords in the Dart programming language.
+ * The enumeration `Keyword` defines the keywords in the Dart programming language.
  * @coverage dart.engine.parser
  */
 class Keyword implements Comparable<Keyword> {
@@ -288,9 +288,9 @@
 
   /**
    * Initialize a newly created keyword to have the given syntax. The keyword is a pseudo-keyword if
-   * the given flag is {@code true}.
+   * the given flag is `true`.
    * @param syntax the lexeme for the keyword
-   * @param isPseudoKeyword {@code true} if this keyword is a pseudo-keyword
+   * @param isPseudoKeyword `true` if this keyword is a pseudo-keyword
    */
   Keyword.con2(this.name, this.ordinal, String syntax2, bool isPseudoKeyword) {
     _jtd_constructor_319_impl(syntax2, isPseudoKeyword);
@@ -307,19 +307,19 @@
   String get syntax => _syntax;
 
   /**
-   * Return {@code true} if this keyword is a pseudo-keyword. Pseudo keywords can be used as
+   * Return `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
+   * @return `true` if this keyword is a pseudo-keyword
    */
-  bool isPseudoKeyword() => _isPseudoKeyword2;
+  bool get isPseudoKeyword => _isPseudoKeyword2;
   int compareTo(Keyword other) => ordinal - other.ordinal;
   int get hashCode => ordinal;
   String toString() => name;
 }
 /**
- * The abstract class {@code AbstractScanner} implements a scanner for Dart code. Subclasses are
+ * The abstract class `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
@@ -415,8 +415,8 @@
   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
+   * Return `true` if any unmatched groups were found during the parse.
+   * @return `true` if any unmatched groups were found during the parse
    */
   bool hasUnmatchedGroups() => _hasUnmatchedGroups2;
 
@@ -764,7 +764,7 @@
       return next;
     }
   }
-  int select4(int choice, TokenType yesType, TokenType noType, int offset) {
+  int select3(int choice, TokenType yesType, TokenType noType, int offset) {
     int next = advance();
     if (next == choice) {
       appendToken2(yesType, offset);
@@ -871,7 +871,7 @@
     if (!hasDigit) {
       appendStringToken(TokenType.INT, getString(start, -2));
       if (0x2E == next) {
-        return select4(0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD, offset - 1);
+        return select3(0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD, offset - 1);
       }
       appendToken2(TokenType.PERIOD, offset - 1);
       return bigSwitch(next);
@@ -1272,7 +1272,7 @@
   }
 }
 /**
- * Instances of the class {@code StringToken} represent a token whose value is independent of it's
+ * Instances of the class `StringToken` represent a token whose value is independent of it's
  * type.
  * @coverage dart.engine.parser
  */
@@ -1296,7 +1296,7 @@
   String value() => _value2;
 }
 /**
- * Instances of the class {@code CharBufferScanner} implement a scanner that reads from a character
+ * Instances of the class `CharBufferScanner` implement a scanner that reads from a character
  * buffer. The scanning logic is in the superclass.
  * @coverage dart.engine.parser
  */
@@ -1344,7 +1344,7 @@
   }
 }
 /**
- * Instances of the class {@code TokenWithComment} represent a normal token that is preceded by
+ * Instances of the class `TokenWithComment` represent a normal token that is preceded by
  * comments.
  * @coverage dart.engine.parser
  */
@@ -1368,7 +1368,7 @@
   Token get precedingComments => _precedingComment;
 }
 /**
- * Instances of the class {@code Token} represent a token that was scanned from the input. Each
+ * Instances of the class `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.
  * @coverage dart.engine.parser
  */
@@ -1437,9 +1437,9 @@
   int get offset => _offset;
 
   /**
-   * Return the first comment in the list of comments that precede this token, or {@code null} if
+   * Return the first comment in the list of comments that precede this token, or `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.
+   * token stream using [getNext] until `null` is returned.
    * @return the first comment in the list of comments that precede this token
    */
   Token get precedingComments => null;
@@ -1457,24 +1457,24 @@
   TokenType get type => _type;
 
   /**
-   * Return {@code true} if this token represents an operator.
-   * @return {@code true} if this token represents an operator
+   * Return `true` if this token represents an operator.
+   * @return `true` if this token represents an operator
    */
-  bool isOperator() => _type.isOperator();
+  bool get isOperator => _type.isOperator;
 
   /**
-   * Return {@code true} if this token is a synthetic token. A synthetic token is a token that was
+   * Return `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
+   * have a length of zero (`0`).
+   * @return `true` if this token is a synthetic token
    */
-  bool isSynthetic() => length == 0;
+  bool get 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
+   * Return `true` if this token represents an operator that can be defined by users.
+   * @return `true` if this token represents an operator that can be defined by users
    */
-  bool isUserDefinableOperator() => _type.isUserDefinableOperator();
+  bool get isUserDefinableOperator => _type.isUserDefinableOperator;
 
   /**
    * Set the next token in the token stream to the given token. This has the side-effect of setting
@@ -1525,7 +1525,7 @@
   }
 }
 /**
- * Instances of the class {@code StringScanner} implement a scanner that reads from a string. The
+ * Instances of the class `StringScanner` implement a scanner that reads from a string. The
  * scanning logic is in the superclass.
  * @coverage dart.engine.parser
  */
@@ -1568,7 +1568,7 @@
   /**
    * 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
@@ -1604,7 +1604,7 @@
   }
 }
 /**
- * Instances of the class {@code BeginTokenWithComment} represent a begin token that is preceded by
+ * Instances of the class `BeginTokenWithComment` represent a begin token that is preceded by
  * comments.
  * @coverage dart.engine.parser
  */
@@ -1628,7 +1628,7 @@
   Token get precedingComments => _precedingComment;
 }
 /**
- * Instances of the class {@code KeywordToken} represent a keyword in the language.
+ * Instances of the class `KeywordToken` represent a keyword in the language.
  * @coverage dart.engine.parser
  */
 class KeywordToken extends Token {
@@ -1656,7 +1656,7 @@
   Keyword value() => _keyword;
 }
 /**
- * Instances of the class {@code BeginToken} represent the opening half of a grouping pair of
+ * Instances of the class `BeginToken` represent the opening half of a grouping pair of
  * tokens. This is used for curly brackets ('{'), parentheses ('('), and square brackets ('\[').
  * @coverage dart.engine.parser
  */
@@ -1691,7 +1691,7 @@
   }
 }
 /**
- * The enumeration {@code TokenClass} represents classes (or groups) of tokens with a similar use.
+ * The enumeration `TokenClass` represents classes (or groups) of tokens with a similar use.
  * @coverage dart.engine.parser
  */
 class TokenClass implements Comparable<TokenClass> {
@@ -1784,7 +1784,7 @@
   final int ordinal;
 
   /**
-   * The precedence of tokens of this class, or {@code 0} if the such tokens do not represent an
+   * The precedence of tokens of this class, or `0` if the such tokens do not represent an
    * operator.
    */
   int _precedence = 0;
@@ -1802,7 +1802,7 @@
   }
 
   /**
-   * Return the precedence of tokens of this class, or {@code 0} if the such tokens do not represent
+   * Return the precedence of tokens of this class, or `0` if the such tokens do not represent
    * an operator.
    * @return the precedence of tokens of this class
    */
@@ -1812,7 +1812,7 @@
   String toString() => name;
 }
 /**
- * Instances of the class {@code KeywordTokenWithComment} implement a keyword token that is preceded
+ * Instances of the class `KeywordTokenWithComment` implement a keyword token that is preceded
  * by comments.
  * @coverage dart.engine.parser
  */
@@ -1836,7 +1836,7 @@
   Token get precedingComments => _precedingComment;
 }
 /**
- * The enumeration {@code TokenType} defines the types of tokens that can be returned by the
+ * The enumeration `TokenType` defines the types of tokens that can be returned by the
  * scanner.
  * @coverage dart.engine.parser
  */
@@ -1927,7 +1927,7 @@
   TokenClass _tokenClass;
 
   /**
-   * The lexeme that defines this type of token, or {@code null} if there is more than one possible
+   * The lexeme that defines this type of token, or `null` if there is more than one possible
    * lexeme for this type of token.
    */
   String _lexeme;
@@ -1946,95 +1946,95 @@
   }
 
   /**
-   * Return the lexeme that defines this type of token, or {@code null} if there is more than one
+   * Return the lexeme that defines this type of token, or `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, or `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
+   * Return `true` if this type of token represents an additive operator.
+   * @return `true` if this type of token represents an additive operator
    */
-  bool isAdditiveOperator() => identical(_tokenClass, TokenClass.ADDITIVE_OPERATOR);
+  bool get isAdditiveOperator => identical(_tokenClass, TokenClass.ADDITIVE_OPERATOR);
 
   /**
-   * Return {@code true} if this type of token represents an assignment operator.
-   * @return {@code true} if this type of token represents an assignment operator
+   * Return `true` if this type of token represents an assignment operator.
+   * @return `true` if this type of token represents an assignment operator
    */
-  bool isAssignmentOperator() => identical(_tokenClass, TokenClass.ASSIGNMENT_OPERATOR);
+  bool get isAssignmentOperator => identical(_tokenClass, TokenClass.ASSIGNMENT_OPERATOR);
 
   /**
-   * Return {@code true} if this type of token represents an associative operator. An associative
-   * operator is an operator for which the following equality is true:{@code (a * b) * c == a * (b * c)}. In other words, if the result of applying the operator to
+   * Return `true` if this type of token represents an associative operator. An associative
+   * operator is an operator for which the following equality is true:`(a * b) * c == a * (b * c)`. In other words, if the result of applying the operator to
    * multiple operands does not depend on the order in which those applications occur.
-   * <p>
+   *
    * Note: This method considers the logical-and and logical-or operators to be associative, even
    * though the order in which the application of those operators can have an effect because
    * evaluation of the right-hand operand is conditional.
-   * @return {@code true} if this type of token represents an associative operator
+   * @return `true` if this type of token represents an associative operator
    */
-  bool isAssociativeOperator() => identical(this, AMPERSAND) || identical(this, AMPERSAND_AMPERSAND) || identical(this, BAR) || identical(this, BAR_BAR) || identical(this, CARET) || identical(this, PLUS) || identical(this, STAR);
+  bool get isAssociativeOperator => identical(this, AMPERSAND) || identical(this, AMPERSAND_AMPERSAND) || identical(this, BAR) || identical(this, BAR_BAR) || identical(this, CARET) || identical(this, PLUS) || identical(this, STAR);
 
   /**
-   * Return {@code true} if this type of token represents an equality operator.
-   * @return {@code true} if this type of token represents an equality operator
+   * Return `true` if this type of token represents an equality operator.
+   * @return `true` if this type of token represents an equality operator
    */
-  bool isEqualityOperator() => identical(_tokenClass, TokenClass.EQUALITY_OPERATOR);
+  bool get isEqualityOperator => identical(_tokenClass, TokenClass.EQUALITY_OPERATOR);
 
   /**
-   * Return {@code true} if this type of token represents an increment operator.
-   * @return {@code true} if this type of token represents an increment operator
+   * Return `true` if this type of token represents an increment operator.
+   * @return `true` if this type of token represents an increment operator
    */
-  bool isIncrementOperator() => identical(_lexeme, "++") || identical(_lexeme, "--");
+  bool get isIncrementOperator => identical(_lexeme, "++") || identical(_lexeme, "--");
 
   /**
-   * Return {@code true} if this type of token represents a multiplicative operator.
-   * @return {@code true} if this type of token represents a multiplicative operator
+   * Return `true` if this type of token represents a multiplicative operator.
+   * @return `true` if this type of token represents a multiplicative operator
    */
-  bool isMultiplicativeOperator() => identical(_tokenClass, TokenClass.MULTIPLICATIVE_OPERATOR);
+  bool get isMultiplicativeOperator => identical(_tokenClass, TokenClass.MULTIPLICATIVE_OPERATOR);
 
   /**
-   * Return {@code true} if this token type represents an operator.
-   * @return {@code true} if this token type represents an operator
+   * Return `true` if this token type represents an operator.
+   * @return `true` if this token type represents an operator
    */
-  bool isOperator() => _tokenClass != TokenClass.NO_CLASS && this != OPEN_PAREN && this != OPEN_SQUARE_BRACKET && this != PERIOD;
+  bool get isOperator => _tokenClass != TokenClass.NO_CLASS && this != OPEN_PAREN && this != OPEN_SQUARE_BRACKET && this != PERIOD;
 
   /**
-   * Return {@code true} if this type of token represents a relational operator.
-   * @return {@code true} if this type of token represents a relational operator
+   * Return `true` if this type of token represents a relational operator.
+   * @return `true` if this type of token represents a relational operator
    */
-  bool isRelationalOperator() => identical(_tokenClass, TokenClass.RELATIONAL_OPERATOR);
+  bool get isRelationalOperator => identical(_tokenClass, TokenClass.RELATIONAL_OPERATOR);
 
   /**
-   * Return {@code true} if this type of token represents a shift operator.
-   * @return {@code true} if this type of token represents a shift operator
+   * Return `true` if this type of token represents a shift operator.
+   * @return `true` if this type of token represents a shift operator
    */
-  bool isShiftOperator() => identical(_tokenClass, TokenClass.SHIFT_OPERATOR);
+  bool get isShiftOperator => identical(_tokenClass, TokenClass.SHIFT_OPERATOR);
 
   /**
-   * Return {@code true} if this type of token represents a unary postfix operator.
-   * @return {@code true} if this type of token represents a unary postfix operator
+   * Return `true` if this type of token represents a unary postfix operator.
+   * @return `true` if this type of token represents a unary postfix operator
    */
-  bool isUnaryPostfixOperator() => identical(_tokenClass, TokenClass.UNARY_POSTFIX_OPERATOR);
+  bool get isUnaryPostfixOperator => identical(_tokenClass, TokenClass.UNARY_POSTFIX_OPERATOR);
 
   /**
-   * Return {@code true} if this type of token represents a unary prefix operator.
-   * @return {@code true} if this type of token represents a unary prefix operator
+   * Return `true` if this type of token represents a unary prefix operator.
+   * @return `true` if this type of token represents a unary prefix operator
    */
-  bool isUnaryPrefixOperator() => identical(_tokenClass, TokenClass.UNARY_PREFIX_OPERATOR);
+  bool get isUnaryPrefixOperator => identical(_tokenClass, TokenClass.UNARY_PREFIX_OPERATOR);
 
   /**
-   * Return {@code true} if this token type represents an operator that can be defined by users.
-   * @return {@code true} if this token type represents an operator that can be defined by users
+   * Return `true` if this token type represents an operator that can be defined by users.
+   * @return `true` if this token type represents an operator that can be defined by users
    */
-  bool isUserDefinableOperator() => identical(_lexeme, "==") || identical(_lexeme, "~") || identical(_lexeme, "[]") || identical(_lexeme, "[]=") || identical(_lexeme, "*") || identical(_lexeme, "/") || identical(_lexeme, "%") || identical(_lexeme, "~/") || identical(_lexeme, "+") || identical(_lexeme, "-") || identical(_lexeme, "<<") || identical(_lexeme, ">>") || identical(_lexeme, ">=") || identical(_lexeme, ">") || identical(_lexeme, "<=") || identical(_lexeme, "<") || identical(_lexeme, "&") || identical(_lexeme, "^") || identical(_lexeme, "|");
+  bool get isUserDefinableOperator => identical(_lexeme, "==") || identical(_lexeme, "~") || identical(_lexeme, "[]") || identical(_lexeme, "[]=") || identical(_lexeme, "*") || identical(_lexeme, "/") || identical(_lexeme, "%") || identical(_lexeme, "~/") || identical(_lexeme, "+") || identical(_lexeme, "-") || identical(_lexeme, "<<") || identical(_lexeme, ">>") || identical(_lexeme, ">=") || identical(_lexeme, ">") || identical(_lexeme, "<=") || identical(_lexeme, "<") || identical(_lexeme, "&") || identical(_lexeme, "^") || identical(_lexeme, "|");
   int compareTo(TokenType other) => ordinal - other.ordinal;
   int get hashCode => ordinal;
   String toString() => name;
diff --git a/pkg/analyzer_experimental/lib/src/generated/sdk.dart b/pkg/analyzer_experimental/lib/src/generated/sdk.dart
index ca85cf4..4f1cc08 100644
--- a/pkg/analyzer_experimental/lib/src/generated/sdk.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/sdk.dart
@@ -17,67 +17,67 @@
   String get category;
 
   /**
-   * Return the path to the file defining the library. The path is relative to the {@code lib}directory within the SDK.
+   * Return the path to the file defining the library. The path is relative to the `lib`directory within the SDK.
    * @return the path to the file defining the library
    */
   String get path;
 
   /**
-   * Return the short name of the library. This is the name used after {@code dart:} in a URI.
+   * Return the short name of the library. This is the name used after `dart:` in a URI.
    * @return the short name of the library
    */
   String get shortName;
 
   /**
-   * Return {@code true} if this library can be compiled to JavaScript by dart2js.
-   * @return {@code true} if this library can be compiled to JavaScript by dart2js
+   * Return `true` if this library can be compiled to JavaScript by dart2js.
+   * @return `true` if this library can be compiled to JavaScript by dart2js
    */
-  bool isDart2JsLibrary();
+  bool get isDart2JsLibrary;
 
   /**
-   * Return {@code true} if the library is documented.
-   * @return {@code true} if the library is documented
+   * Return `true` if the library is documented.
+   * @return `true` if the library is documented
    */
-  bool isDocumented();
+  bool get isDocumented;
 
   /**
-   * Return {@code true} if the library is an implementation library.
-   * @return {@code true} if the library is an implementation library
+   * Return `true` if the library is an implementation library.
+   * @return `true` if the library is an implementation library
    */
-  bool isImplementation();
+  bool get isImplementation;
 
   /**
-   * Return {@code true} if library is internal can be used only by other SDK libraries.
-   * @return {@code true} if library is internal can be used only by other SDK libraries
+   * Return `true` if library is internal can be used only by other SDK libraries.
+   * @return `true` if library is internal can be used only by other SDK libraries
    */
-  bool isInternal();
+  bool get isInternal;
 
   /**
-   * Return {@code true} if library can be used for both client and server.
-   * @return {@code true} if this library can be used for both client and server.
+   * Return `true` if library can be used for both client and server.
+   * @return `true` if this library can be used for both client and server.
    */
-  bool isShared();
+  bool get isShared;
 
   /**
-   * Return {@code true} if this library can be run on the VM.
-   * @return {@code true} if this library can be run on the VM
+   * Return `true` if this library can be run on the VM.
+   * @return `true` if this library can be run on the VM
    */
-  bool isVmLibrary();
+  bool get isVmLibrary;
 }
 /**
- * Instances of the class {@code SdkLibrary} represent the information known about a single library
+ * Instances of the class `SdkLibrary` represent the information known about a single library
  * within the SDK.
  * @coverage dart.engine.sdk
  */
 class SdkLibraryImpl implements SdkLibrary {
 
   /**
-   * The short name of the library. This is the name used after {@code dart:} in a URI.
+   * The short name of the library. This is the name used after `dart:` in a URI.
    */
   String _shortName = null;
 
   /**
-   * The path to the file defining the library. The path is relative to the {@code lib} directory
+   * The path to the file defining the library. The path is relative to the `lib` directory
    * within the SDK.
    */
   String _path = null;
@@ -125,21 +125,21 @@
   String get category => _category;
   String get path => _path;
   String get shortName => _shortName;
-  bool isDart2JsLibrary() => (_platforms & DART2JS_PLATFORM) != 0;
-  bool isDocumented() => _documented;
-  bool isImplementation() => _implementation;
-  bool isInternal() => "Internal" == _category;
+  bool get isDart2JsLibrary => (_platforms & DART2JS_PLATFORM) != 0;
+  bool get isDocumented => _documented;
+  bool get isImplementation => _implementation;
+  bool get isInternal => "Internal" == _category;
 
   /**
-   * Return {@code true} if library can be used for both client and server
+   * Return `true` if library can be used for both client and server
    */
-  bool isShared() => _category == "Shared";
+  bool get isShared => _category == "Shared";
 
   /**
-   * Return {@code true} if this library can be run on the VM.
-   * @return {@code true} if this library can be run on the VM
+   * Return `true` if this library can be run on the VM.
+   * @return `true` if this library can be run on the VM
    */
-  bool isVmLibrary() => (_platforms & VM_PLATFORM) != 0;
+  bool get isVmLibrary => (_platforms & VM_PLATFORM) != 0;
 
   /**
    * Set the name of the category containing the library to the given name.
@@ -158,7 +158,7 @@
 
   /**
    * Set whether the library is documented to match the given value.
-   * @param documented {@code true} if the library is documented
+   * @param documented `true` if the library is documented
    */
   void set documented(bool documented2) {
     this._documented = documented2;
@@ -166,14 +166,14 @@
 
   /**
    * Set whether the library is an implementation library to match the given value.
-   * @param implementation {@code true} if the library is an implementation library
+   * @param implementation `true` if the library is an implementation library
    */
   void set implementation(bool implementation2) {
     this._implementation = implementation2;
   }
 
   /**
-   * Set the path to the file defining the library to the given path. The path is relative to the{@code lib} directory within the SDK.
+   * Set the path to the file defining the library to the given path. The path is relative to the`lib` directory within the SDK.
    * @param path the path to the file defining the library
    */
   void set path(String path2) {
@@ -188,7 +188,7 @@
   }
 }
 /**
- * Instances of the class {@code LibraryMap} map Dart library URI's to the {@link SdkLibraryImpllibrary}.
+ * Instances of the class `LibraryMap` map Dart library URI's to the [SdkLibraryImpllibrary].
  * @coverage dart.engine.sdk
  */
 class LibraryMap {
@@ -199,14 +199,14 @@
   Map<String, SdkLibraryImpl> _libraryMap = new Map<String, SdkLibraryImpl>();
 
   /**
-   * Return the library with the given URI, or {@code null} if the URI does not map to a library.
+   * Return the library with the given URI, or `null` if the URI does not map to a library.
    * @param dartUri the URI of the library to be returned
    * @return the library with the given URI
    */
   SdkLibrary getLibrary(String dartUri) => _libraryMap[dartUri];
 
   /**
-   * Return an array containing all the sdk libraries {@link SdkLibraryImpl} in the mapping
+   * Return an array containing all the sdk libraries [SdkLibraryImpl] in the mapping
    * @return the sdk libraries in the mapping
    */
   List<SdkLibrary> get sdkLibraries => new List.from(_libraryMap.values);
@@ -218,7 +218,7 @@
   List<String> get uris => new List.from(_libraryMap.keys.toSet());
 
   /**
-   * Return the library with the given URI, or {@code null} if the URI does not map to a library.
+   * Return the library with the given URI, or `null` if the URI does not map to a library.
    * @param dartUri the URI of the library to be returned
    * @param library the library with the given URI
    */
@@ -233,7 +233,7 @@
   int size() => _libraryMap.length;
 }
 /**
- * Instances of the class {@code DartSdk} represent a Dart SDK installed in a specified location.
+ * Instances of the class `DartSdk` represent a Dart SDK installed in a specified location.
  * @coverage dart.engine.sdk
  */
 abstract class DartSdk {
@@ -264,8 +264,8 @@
   Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri);
 
   /**
-   * Return the {@link AnalysisContext} used for all of the sources in this {@link DartSdk}.
-   * @return the {@link AnalysisContext} used for all of the sources in this {@link DartSdk}
+   * Return the [AnalysisContext] used for all of the sources in this [DartSdk].
+   * @return the [AnalysisContext] used for all of the sources in this [DartSdk]
    */
   AnalysisContext get context;
 
@@ -276,14 +276,14 @@
   List<SdkLibrary> get sdkLibraries;
 
   /**
-   * Return the library representing the library with the given {@code dart:} URI, or {@code null}if the given URI does not denote a library in this SDK.
+   * Return the library representing the library with the given `dart:` URI, or `null`if the given URI does not denote a library in this SDK.
    * @param dartUri the URI of the library to be returned
    * @return the SDK library object
    */
   SdkLibrary getSdkLibrary(String dartUri);
 
   /**
-   * Return the revision number of this SDK, or {@code "0"} if the revision number cannot be
+   * Return the revision number of this SDK, or `"0"` if the revision number cannot be
    * discovered.
    * @return the revision number of this SDK
    */
@@ -296,7 +296,7 @@
   List<String> get uris;
 
   /**
-   * Return the source representing the library with the given {@code dart:} URI, or {@code null} if
+   * Return the source representing the library with the given `dart:` URI, or `null` if
    * the given URI does not denote a library in this SDK.
    * @param contentCache the content cache used to access the contents of the mapped source
    * @param dartUri the URI of the library to be returned
diff --git a/pkg/analyzer_experimental/lib/src/generated/sdk_io.dart b/pkg/analyzer_experimental/lib/src/generated/sdk_io.dart
index baf26d7..5bcead2 100644
--- a/pkg/analyzer_experimental/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/sdk_io.dart
@@ -14,14 +14,14 @@
 import 'sdk.dart';
 import 'engine.dart';
 /**
- * Instances of the class {@code DirectoryBasedDartSdk} represent a Dart SDK installed in a
+ * Instances of the class `DirectoryBasedDartSdk` represent a Dart SDK installed in a
  * specified directory.
  * @coverage dart.engine.sdk
  */
 class DirectoryBasedDartSdk implements DartSdk {
 
   /**
-   * The {@link AnalysisContext} which is used for all of the sources in this {@link DartSdk}.
+   * The [AnalysisContext] which is used for all of the sources in this [DartSdk].
    */
   InternalAnalysisContext _analysisContext;
 
@@ -31,7 +31,7 @@
   JavaFile _sdkDirectory;
 
   /**
-   * The revision number of this SDK, or {@code "0"} if the revision number cannot be discovered.
+   * The revision number of this SDK, or `"0"` if the revision number cannot be discovered.
    */
   String _sdkVersion;
 
@@ -81,7 +81,7 @@
   static String _DARTIUM_EXECUTABLE_NAME_WIN = "Chrome.exe";
 
   /**
-   * The name of the {@link System} property whose value is the path to the default Dart SDK
+   * The name of the [System] property whose value is the path to the default Dart SDK
    * directory.
    */
   static String _DEFAULT_DIRECTORY_PROPERTY_NAME = "com.google.dart.sdk";
@@ -129,7 +129,7 @@
   static String _VM_EXECUTABLE_NAME = "dart";
 
   /**
-   * Return the default Dart SDK, or {@code null} if the directory containing the default SDK cannot
+   * Return the default Dart SDK, or `null` if the directory containing the default SDK cannot
    * be determined (or does not exist).
    * @return the default Dart SDK
    */
@@ -142,10 +142,10 @@
   }
 
   /**
-   * Return the default directory for the Dart SDK, or {@code null} if the directory cannot be
-   * determined (or does not exist). The default directory is provided by a {@link System} property
-   * named {@code com.google.dart.sdk}, or, if the property is not defined, an environment variable
-   * named {@code DART_SDK}.
+   * Return the default directory for the Dart SDK, or `null` if the directory cannot be
+   * determined (or does not exist). The default directory is provided by a [System] property
+   * named `com.google.dart.sdk`, or, if the property is not defined, an environment variable
+   * named `DART_SDK`.
    * @return the default directory for the Dart SDK
    */
   static JavaFile get defaultSdkDirectory {
@@ -184,7 +184,7 @@
   AnalysisContext get context => _analysisContext;
 
   /**
-   * Return the file containing the Dartium executable, or {@code null} if it does not exist.
+   * Return the file containing the Dartium executable, or `null` if it does not exist.
    * @return the file containing the Dartium executable
    */
   JavaFile get dartiumExecutable {
@@ -219,7 +219,7 @@
   JavaFile get docDirectory => new JavaFile.relative(_sdkDirectory, _DOCS_DIRECTORY_NAME);
 
   /**
-   * Return the auxiliary documentation file for the given library, or {@code null} if no such file
+   * Return the auxiliary documentation file for the given library, or `null` if no such file
    * exists.
    * @param libraryName the name of the library associated with the documentation file to be
    * returned
@@ -247,7 +247,7 @@
   SdkLibrary getSdkLibrary(String dartUri) => _libraryMap.getLibrary(dartUri);
 
   /**
-   * Return the revision number of this SDK, or {@code "0"} if the revision number cannot be
+   * Return the revision number of this SDK, or `"0"` if the revision number cannot be
    * discovered.
    * @return the revision number of this SDK
    */
@@ -275,7 +275,7 @@
   List<String> get uris => _libraryMap.uris;
 
   /**
-   * Return the file containing the VM executable, or {@code null} if it does not exist.
+   * Return the file containing the VM executable, or `null` if it does not exist.
    * @return the file containing the VM executable
    */
   JavaFile get vmExecutable {
@@ -291,16 +291,16 @@
   }
 
   /**
-   * Return {@code true} if this SDK includes documentation.
-   * @return {@code true} if this installation of the SDK has documentation
+   * Return `true` if this SDK includes documentation.
+   * @return `true` if this installation of the SDK has documentation
    */
   bool hasDocumentation() => docDirectory.exists();
 
   /**
-   * Return {@code true} if the Dartium binary is available.
-   * @return {@code true} if the Dartium binary is available
+   * Return `true` if the Dartium binary is available.
+   * @return `true` if the Dartium binary is available
    */
-  bool isDartiumInstalled() => dartiumExecutable != null;
+  bool get isDartiumInstalled => dartiumExecutable != null;
   Source mapDartUri(ContentCache contentCache, String dartUri) {
     SdkLibrary library = getSdkLibrary(dartUri);
     if (library == null) {
@@ -366,7 +366,7 @@
   }
 }
 /**
- * Instances of the class {@code SdkLibrariesReader} read and parse the libraries file
+ * Instances of the class `SdkLibrariesReader` read and parse the libraries file
  * (dart-sdk/lib/_internal/libraries.dart) for information about the libraries in an SDK. The
  * library information is represented as a Dart file containing a single top-level variable whose
  * value is a const map. The keys of the map are the names of libraries defined in the SDK and the
@@ -438,7 +438,7 @@
   static String _PLATFORMS = "platforms";
 
   /**
-   * The value of the {@link #PLATFORMS platforms} parameter used to specify that the library can
+   * The value of the [PLATFORMS platforms] parameter used to specify that the library can
    * be used on the VM.
    */
   static String _VM_PLATFORM = "VM_PLATFORM";
diff --git a/pkg/analyzer_experimental/lib/src/generated/source.dart b/pkg/analyzer_experimental/lib/src/generated/source.dart
index da272e9..d149b4b 100644
--- a/pkg/analyzer_experimental/lib/src/generated/source.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/source.dart
@@ -5,7 +5,7 @@
 import 'sdk.dart' show DartSdk;
 import 'engine.dart' show AnalysisContext;
 /**
- * Instances of the class {@code SourceFactory} resolve possibly relative URI's against an existing{@link Source source}.
+ * Instances of the class `SourceFactory` resolve possibly relative URI's against an existing[Source source].
  * @coverage dart.engine.source
  */
 class SourceFactory {
@@ -50,7 +50,7 @@
   }
 
   /**
-   * Return a source object representing the given absolute URI, or {@code null} if the URI is not a
+   * Return a source object representing the given absolute URI, or `null` if the URI is not a
    * valid URI or if it is not an absolute URI.
    * @param absoluteUri the absolute URI to be resolved
    * @return a source object representing the absolute URI
@@ -108,9 +108,9 @@
   AnalysisContext get context => _context;
 
   /**
-   * Return the {@link DartSdk} associated with this {@link SourceFactory}, or {@code null} if there
+   * Return the [DartSdk] associated with this [SourceFactory], or `null` if there
    * is no such SDK.
-   * @return the {@link DartSdk} associated with this {@link SourceFactory}, or {@code null} if
+   * @return the [DartSdk] associated with this [SourceFactory], or `null` if
    * there is no such SDK
    */
   DartSdk get dartSdk {
@@ -125,7 +125,7 @@
 
   /**
    * Return a source object representing the URI that results from resolving the given (possibly
-   * relative) contained URI against the URI associated with an existing source object, or{@code null} if either the contained URI is invalid or if it cannot be resolved against the
+   * relative) contained URI against the URI associated with an existing source object, or`null` if either the contained URI is invalid or if it cannot be resolved against the
    * source object's URI.
    * @param containingSource the source containing the given URI
    * @param containedUri the (possibly relative) URI to be resolved against the containing source
@@ -142,7 +142,7 @@
   /**
    * Return an absolute URI that represents the given source.
    * @param source the source to get URI for
-   * @return the absolute URI representing the given source, may be {@code null}
+   * @return the absolute URI representing the given source, may be `null`
    */
   Uri restoreUri(Source source) {
     for (UriResolver resolver in _resolvers) {
@@ -156,7 +156,7 @@
 
   /**
    * Set the contents of the given source to the given contents. This has the effect of overriding
-   * the default contents of the source. If the contents are {@code null} the override is removed so
+   * the default contents of the source. If the contents are `null` the override is removed so
    * that the default contents will be returned.
    * @param source the source whose contents are being overridden
    * @param contents the new contents of the source
@@ -167,8 +167,8 @@
 
   /**
    * Set the analysis context that this source factory is associated with to the given context.
-   * <p>
-   * <b>Note:</b> This method should only be invoked by{@link AnalysisContextImpl#setSourceFactory(SourceFactory)} and is only public out of
+   *
+   * <b>Note:</b> This method should only be invoked by[AnalysisContextImpl#setSourceFactory] and is only public out of
    * necessity.
    * @param context the analysis context that this source factory is associated with
    */
@@ -177,20 +177,20 @@
   }
 
   /**
-   * Return the contents of the given source, or {@code null} if this factory does not override the
+   * Return the contents of the given source, or `null` if this factory does not override the
    * contents of the source.
-   * <p>
-   * <b>Note:</b> This method is not intended to be used except by{@link FileBasedSource#getContents(com.google.dart.engine.source.Source.ContentReceiver)}.
+   *
+   * <b>Note:</b> This method is not intended to be used except by[FileBasedSource#getContents].
    * @param source the source whose content is to be returned
    * @return the contents of the given source
    */
   String getContents(Source source) => _contentCache.getContents(source);
 
   /**
-   * Return the modification stamp of the given source, or {@code null} if this factory does not
+   * Return the modification stamp of the given source, or `null` if this factory does not
    * override the contents of the source.
-   * <p>
-   * <b>Note:</b> This method is not intended to be used except by{@link FileBasedSource#getModificationStamp()}.
+   *
+   * <b>Note:</b> This method is not intended to be used except by[FileBasedSource#getModificationStamp].
    * @param source the source whose modification stamp is to be returned
    * @return the modification stamp of the given source
    */
@@ -198,7 +198,7 @@
 
   /**
    * Return a source object representing the URI that results from resolving the given (possibly
-   * relative) contained URI against the URI associated with an existing source object, or{@code null} if either the contained URI is invalid or if it cannot be resolved against the
+   * relative) contained URI against the URI associated with an existing source object, or`null` if either the contained URI is invalid or if it cannot be resolved against the
    * source object's URI.
    * @param containingSource the source containing the given URI
    * @param containedUri the (possibly relative) URI to be resolved against the containing source
@@ -219,7 +219,7 @@
   }
 }
 /**
- * The abstract class {@code UriResolver} defines the behavior of objects that are used to resolve
+ * The abstract class `UriResolver` defines the behavior of objects that are used to resolve
  * URI's for a source factory. Subclasses of this class are expected to resolve a single scheme of
  * absolute URI.
  * @coverage dart.engine.source
@@ -228,34 +228,34 @@
 
   /**
    * If this resolver should be used for URI's of the given kind, resolve the given absolute URI.
-   * The URI does not need to have the scheme handled by this resolver if the kind matches. Return a{@link Source source} representing the file to which it was resolved, or {@code null} if it
+   * The URI does not need to have the scheme handled by this resolver if the kind matches. Return a[Source source] representing the file to which it was resolved, or `null` if it
    * could not be resolved.
    * @param contentCache the content cache used to access the contents of the returned source
    * @param kind the kind of URI that was originally resolved in order to produce an encoding with
    * the given URI
    * @param uri the URI to be resolved
-   * @return a {@link Source source} representing the file to which given URI was resolved
+   * @return a [Source source] representing the file to which given URI was resolved
    */
   Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri);
 
   /**
-   * Resolve the given absolute URI. Return a {@link Source source} representing the file to which
-   * it was resolved, or {@code null} if it could not be resolved.
+   * Resolve the given absolute URI. Return a [Source source] representing the file to which
+   * it was resolved, or `null` if it could not be resolved.
    * @param contentCache the content cache used to access the contents of the returned source
    * @param uri the URI to be resolved
-   * @return a {@link Source source} representing the file to which given URI was resolved
+   * @return a [Source source] representing the file to which given URI was resolved
    */
   Source resolveAbsolute(ContentCache contentCache, Uri uri);
 
   /**
    * Return an absolute URI that represents the given source.
    * @param source the source to get URI for
-   * @return the absolute URI representing the given source, may be {@code null}
+   * @return the absolute URI representing the given source, may be `null`
    */
   Uri restoreAbsolute(Source source) => null;
 }
 /**
- * The interface {@code Source} defines the behavior of objects representing source code that can be
+ * The interface `Source` defines the behavior of objects representing source code that can be
  * compiled.
  * @coverage dart.engine.source
  */
@@ -267,18 +267,18 @@
   static final List<Source> EMPTY_ARRAY = new List<Source>(0);
 
   /**
-   * Return {@code true} if the given object is a source that represents the same source code as
+   * Return `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
+   * @return `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);
 
   /**
-   * Return {@code true} if this source exists.
-   * @return {@code true} if this source exists
+   * Return `true` if this source exists.
+   * @return `true` if this source exists
    */
   bool exists();
 
@@ -342,27 +342,27 @@
   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
+   * Return `true` if this source is in one of the system libraries.
+   * @return `true` if this is in a system library
    */
-  bool isInSystemLibrary();
+  bool get isInSystemLibrary;
 
   /**
-   * Resolve the relative URI against the URI associated with this source object. Return a{@link Source source} representing the URI to which it was resolved, or {@code null} if it
+   * Resolve the relative URI against the URI associated with this source object. Return a[Source source] representing the URI to which it was resolved, or `null` if it
    * could not be resolved.
-   * <p>
+   *
    * Note: This method is not intended for public use, it is only visible out of necessity. It is
-   * only intended to be invoked by a {@link SourceFactory source factory}. Source factories will
+   * only intended to be invoked by a [SourceFactory source factory]. Source factories will
    * only invoke this method if the URI is relative, so implementations of this method are not
    * required to, and generally do not, verify the argument. The result of invoking this method with
    * an absolute URI is intentionally left unspecified.
    * @param relativeUri the relative URI to be resolved against the containing source
-   * @return a {@link Source source} representing the URI to which given URI was resolved
+   * @return a [Source source] representing the URI to which given URI was resolved
    */
   Source resolveRelative(Uri relativeUri);
 }
 /**
- * The interface {@code ContentReceiver} defines the behavior of objects that can receive the
+ * The interface `ContentReceiver` defines the behavior of objects that can receive the
  * content of a source.
  */
 abstract class Source_ContentReceiver {
@@ -382,7 +382,7 @@
   void accept2(String contents, int modificationTime);
 }
 /**
- * The enumeration {@code SourceKind} defines the different kinds of sources that are known to the
+ * The enumeration `SourceKind` defines the different kinds of sources that are known to the
  * analysis engine.
  * @coverage dart.engine.source
  */
@@ -424,7 +424,7 @@
   String toString() => name;
 }
 /**
- * The enumeration {@code UriKind} defines the different kinds of URI's that are known to the
+ * The enumeration `UriKind` defines the different kinds of URI's that are known to the
  * analysis engine. These are used to keep track of the kind of URI associated with a given source.
  * @coverage dart.engine.source
  */
@@ -466,7 +466,7 @@
   }
 
   /**
-   * Return the URI kind represented by the given encoding, or {@code null} if there is no kind with
+   * Return the URI kind represented by the given encoding, or `null` if there is no kind with
    * the given encoding.
    * @param encoding the single character encoding used to identify the URI kind to be returned
    * @return the URI kind represented by the given encoding
@@ -495,7 +495,7 @@
   String toString() => name;
 }
 /**
- * A source range defines an {@link Element}'s source coordinates relative to its {@link Source}.
+ * A source range defines an [Element]'s source coordinates relative to its [Source].
  * @coverage dart.engine.utilities
  */
 class SourceRange {
@@ -523,27 +523,27 @@
   }
 
   /**
-   * @return {@code true} if <code>x</code> is in \[offset, offset + length) interval.
+   * @return `true` if <code>x</code> is in \[offset, offset + length) interval.
    */
   bool contains(int x) => _offset <= x && x < _offset + _length;
 
   /**
-   * @return {@code true} if <code>x</code> is in (offset, offset + length) interval.
+   * @return `true` if <code>x</code> is in (offset, offset + length) interval.
    */
   bool containsExclusive(int x) => _offset < x && x < _offset + _length;
 
   /**
-   * @return {@code true} if <code>otherRange</code> covers this {@link SourceRange}.
+   * @return `true` if <code>otherRange</code> covers this [SourceRange].
    */
   bool coveredBy(SourceRange otherRange) => otherRange.covers(this);
 
   /**
-   * @return {@code true} if this {@link SourceRange} covers <code>otherRange</code>.
+   * @return `true` if this [SourceRange] covers <code>otherRange</code>.
    */
   bool covers(SourceRange otherRange) => offset <= otherRange.offset && otherRange.end <= end;
 
   /**
-   * @return {@code true} if this {@link SourceRange} ends in <code>otherRange</code>.
+   * @return `true` if this [SourceRange] ends in <code>otherRange</code>.
    */
   bool endsIn(SourceRange otherRange) {
     int thisEnd = end;
@@ -564,7 +564,7 @@
   int get end => _offset + _length;
 
   /**
-   * @return the expanded instance of {@link SourceRange}, which has the same center.
+   * @return the expanded instance of [SourceRange], which has the same center.
    */
   SourceRange getExpanded(int delta) => new SourceRange(_offset - delta, delta + _length + delta);
 
@@ -577,7 +577,7 @@
   int get length => _length;
 
   /**
-   * @return the instance of {@link SourceRange} with end moved on "delta".
+   * @return the instance of [SourceRange] with end moved on "delta".
    */
   SourceRange getMoveEnd(int delta) => new SourceRange(_offset, _length + delta);
 
@@ -590,13 +590,13 @@
   int get offset => _offset;
 
   /**
-   * @return the expanded translated of {@link SourceRange}, with moved start and the same length.
+   * @return the expanded translated of [SourceRange], with moved start and the same length.
    */
   SourceRange getTranslated(int delta) => new SourceRange(_offset + delta, _length);
   int get hashCode => 31 * _offset + _length;
 
   /**
-   * @return {@code true} if this {@link SourceRange} intersects with given.
+   * @return `true` if this [SourceRange] intersects with given.
    */
   bool intersects(SourceRange other) {
     if (other == null) {
@@ -612,7 +612,7 @@
   }
 
   /**
-   * @return {@code true} if this {@link SourceRange} starts in <code>otherRange</code>.
+   * @return `true` if this [SourceRange] starts in <code>otherRange</code>.
    */
   bool startsIn(SourceRange otherRange) => otherRange.contains(_offset);
   String toString() {
@@ -626,8 +626,8 @@
   }
 }
 /**
- * The interface {@code SourceContainer} is used by clients to define a collection of sources
- * <p>
+ * The interface `SourceContainer` is used by clients to define a collection of sources
+ *
  * Source containers are not used within analysis engine, but can be used by clients to group
  * sources for the purposes of accessing composite dependency information. For example, the Eclipse
  * client uses source containers to represent Eclipse projects, which allows it to easily compute
@@ -639,12 +639,12 @@
   /**
    * Determine if the specified source is part of the receiver's collection of sources.
    * @param source the source in question
-   * @return {@code true} if the receiver contains the source, else {@code false}
+   * @return `true` if the receiver contains the source, else `false`
    */
   bool contains(Source source);
 }
 /**
- * Instances of the class {@code DartUriResolver} resolve {@code dart} URI's.
+ * Instances of the class `DartUriResolver` resolve `dart` URI's.
  * @coverage dart.engine.source
  */
 class DartUriResolver extends UriResolver {
@@ -655,14 +655,14 @@
   DartSdk _sdk;
 
   /**
-   * The name of the {@code dart} scheme.
+   * The name of the `dart` scheme.
    */
   static String _DART_SCHEME = "dart";
 
   /**
-   * Return {@code true} if the given URI is a {@code dart:} URI.
+   * Return `true` if the given URI is a `dart:` URI.
    * @param uri the URI being tested
-   * @return {@code true} if the given URI is a {@code dart:} URI
+   * @return `true` if the given URI is a `dart:` URI
    */
   static bool isDartUri(Uri uri) => _DART_SCHEME == uri.scheme;
 
@@ -682,8 +682,8 @@
   }
 
   /**
-   * Return the {@link DartSdk} against which URIs are to be resolved.
-   * @return the {@link DartSdk} against which URIs are to be resolved.
+   * Return the [DartSdk] against which URIs are to be resolved.
+   * @return the [DartSdk] against which URIs are to be resolved.
    */
   DartSdk get dartSdk => _sdk;
   Source resolveAbsolute(ContentCache contentCache, Uri uri) {
@@ -694,7 +694,7 @@
   }
 }
 /**
- * Instances of the class {@code LineInfo} encapsulate information about line and column information
+ * Instances of the class `LineInfo` encapsulate information about line and column information
  * within a source file.
  * @coverage dart.engine.utilities
  */
@@ -735,7 +735,7 @@
   }
 }
 /**
- * Instances of the class {@code Location} represent the location of a character as a line and
+ * Instances of the class `Location` represent the location of a character as a line and
  * column pair.
  */
 class LineInfo_Location {
@@ -774,7 +774,7 @@
   int get lineNumber => _lineNumber;
 }
 /**
- * Instances of class {@code ContentCache} hold content used to override the default content of a{@link Source}.
+ * Instances of class `ContentCache` hold content used to override the default content of a[Source].
  * @coverage dart.engine.source
  */
 class ContentCache {
@@ -792,20 +792,20 @@
   Map<Source, int> _stampMap = new Map<Source, int>();
 
   /**
-   * Return the contents of the given source, or {@code null} if this cache does not override the
+   * Return the contents of the given source, or `null` if this cache does not override the
    * contents of the source.
-   * <p>
-   * <b>Note:</b> This method is not intended to be used except by{@link SourceFactory#getContents(com.google.dart.engine.source.Source.ContentReceiver)}.
+   *
+   * <b>Note:</b> This method is not intended to be used except by[SourceFactory#getContents].
    * @param source the source whose content is to be returned
    * @return the contents of the given source
    */
   String getContents(Source source) => _contentMap[source];
 
   /**
-   * Return the modification stamp of the given source, or {@code null} if this cache does not
+   * Return the modification stamp of the given source, or `null` if this cache does not
    * override the contents of the source.
-   * <p>
-   * <b>Note:</b> This method is not intended to be used except by{@link SourceFactory#getModificationStamp(com.google.dart.engine.source.Source)}.
+   *
+   * <b>Note:</b> This method is not intended to be used except by[SourceFactory#getModificationStamp].
    * @param source the source whose modification stamp is to be returned
    * @return the modification stamp of the given source
    */
@@ -813,7 +813,7 @@
 
   /**
    * Set the contents of the given source to the given contents. This has the effect of overriding
-   * the default contents of the source. If the contents are {@code null} the override is removed so
+   * the default contents of the source. If the contents are `null` the override is removed so
    * that the default contents will be returned.
    * @param source the source whose contents are being overridden
    * @param contents the new contents of the source
diff --git a/pkg/analyzer_experimental/lib/src/generated/source_io.dart b/pkg/analyzer_experimental/lib/src/generated/source_io.dart
index 98d8fc0..513f77f 100644
--- a/pkg/analyzer_experimental/lib/src/generated/source_io.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/source_io.dart
@@ -9,7 +9,7 @@
 import 'engine.dart' show AnalysisContext, AnalysisEngine;
 export 'source.dart';
 /**
- * Instances of the class {@code FileBasedSource} implement a source that represents a file.
+ * Instances of the class `FileBasedSource` implement a source that represents a file.
  * @coverage dart.engine.source
  */
 class FileBasedSource implements Source {
@@ -52,7 +52,7 @@
    * Initialize a newly created source object.
    * @param contentCache the content cache used to access the contents of this source
    * @param file the file represented by this source
-   * @param flags {@code true} if this source is in one of the system libraries
+   * @param flags `true` if this source is in one of the system libraries
    */
   FileBasedSource.con2(ContentCache contentCache2, JavaFile file2, UriKind uriKind2) {
     _jtd_constructor_339_impl(contentCache2, file2, uriKind2);
@@ -87,7 +87,7 @@
   String get shortName => _file.getName();
   UriKind get uriKind => _uriKind;
   int get hashCode => _file.hashCode;
-  bool isInSystemLibrary() => identical(_uriKind, UriKind.DART_URI);
+  bool get isInSystemLibrary => identical(_uriKind, UriKind.DART_URI);
   Source resolveRelative(Uri containedUri) {
     try {
       Uri resolvedUri = file.toURI().resolveUri(containedUri);
@@ -105,15 +105,15 @@
 
   /**
    * Return the file represented by this source. This is an internal method that is only intended to
-   * be used by {@link UriResolver}.
+   * be used by [UriResolver].
    * @return the file represented by this source
    */
   JavaFile get file => _file;
 }
 /**
- * Instances of the class {@code PackageUriResolver} resolve {@code package} URI's in the context of
+ * Instances of the class `PackageUriResolver` resolve `package` URI's in the context of
  * an application.
- * <p>
+ *
  * For the purposes of sharing analysis, the path to each package under the "packages" directory
  * should be canonicalized, but to preserve relative links within a package, the remainder of the
  * path from the package directory to the leaf should not.
@@ -122,12 +122,12 @@
 class PackageUriResolver extends UriResolver {
 
   /**
-   * The package directories that {@code package} URI's are assumed to be relative to.
+   * The package directories that `package` URI's are assumed to be relative to.
    */
   List<JavaFile> _packagesDirectories;
 
   /**
-   * The name of the {@code package} scheme.
+   * The name of the `package` scheme.
    */
   static String PACKAGE_SCHEME = "package";
 
@@ -137,16 +137,16 @@
   static bool _CanLogRequiredKeyIoException = true;
 
   /**
-   * Return {@code true} if the given URI is a {@code package} URI.
+   * Return `true` if the given URI is a `package` URI.
    * @param uri the URI being tested
-   * @return {@code true} if the given URI is a {@code package} URI
+   * @return `true` if the given URI is a `package` URI
    */
   static bool isPackageUri(Uri uri) => PACKAGE_SCHEME == uri.scheme;
 
   /**
-   * Initialize a newly created resolver to resolve {@code package} URI's relative to the given
+   * Initialize a newly created resolver to resolve `package` URI's relative to the given
    * package directories.
-   * @param packagesDirectories the package directories that {@code package} URI's are assumed to be
+   * @param packagesDirectories the package directories that `package` URI's are assumed to be
    * relative to
    */
   PackageUriResolver(List<JavaFile> packagesDirectories) {
@@ -216,11 +216,11 @@
 
   /**
    * Answer the canonical file for the specified package.
-   * @param packagesDirectory the "packages" directory (not {@code null})
-   * @param pkgName the package name (not {@code null}, not empty)
-   * @param relPath the path relative to the package directory (not {@code null}, no leading slash,
+   * @param packagesDirectory the "packages" directory (not `null`)
+   * @param pkgName the package name (not `null`, not empty)
+   * @param relPath the path relative to the package directory (not `null`, no leading slash,
    * but may be empty string)
-   * @return the file (not {@code null})
+   * @return the file (not `null`)
    */
   JavaFile getCanonicalFile(JavaFile packagesDirectory, String pkgName, String relPath) {
     JavaFile pkgDir = new JavaFile.relative(packagesDirectory, pkgName);
@@ -238,7 +238,7 @@
   }
 }
 /**
- * Instances of the class {@link DirectoryBasedSourceContainer} represent a source container that
+ * Instances of the class [DirectoryBasedSourceContainer] represent a source container that
  * contains all sources within a given directory.
  * @coverage dart.engine.source
  */
@@ -258,14 +258,14 @@
   }
 
   /**
-   * The container's path (not {@code null}).
+   * The container's path (not `null`).
    */
   String _path;
 
   /**
-   * Construct a container representing the specified directory and containing any sources whose{@link Source#getFullName()} starts with the directory's path. This is a convenience method,
-   * fully equivalent to {@link DirectoryBasedSourceContainer#DirectoryBasedSourceContainer(String)}.
-   * @param directory the directory (not {@code null})
+   * Construct a container representing the specified directory and containing any sources whose[Source#getFullName] starts with the directory's path. This is a convenience method,
+   * fully equivalent to [DirectoryBasedSourceContainer#DirectoryBasedSourceContainer].
+   * @param directory the directory (not `null`)
    */
   DirectoryBasedSourceContainer.con1(JavaFile directory) {
     _jtd_constructor_336_impl(directory);
@@ -275,8 +275,8 @@
   }
 
   /**
-   * Construct a container representing the specified path and containing any sources whose{@link Source#getFullName()} starts with the specified path.
-   * @param path the path (not {@code null} and not empty)
+   * Construct a container representing the specified path and containing any sources whose[Source#getFullName] starts with the specified path.
+   * @param path the path (not `null` and not empty)
    */
   DirectoryBasedSourceContainer.con2(String path2) {
     _jtd_constructor_337_impl(path2);
@@ -289,27 +289,27 @@
 
   /**
    * Answer the receiver's path, used to determine if a source is contained in the receiver.
-   * @return the path (not {@code null}, not empty)
+   * @return the path (not `null`, not empty)
    */
   String get path => _path;
   int get hashCode => _path.hashCode;
   String toString() => "SourceContainer[${_path}]";
 }
 /**
- * Instances of the class {@code FileUriResolver} resolve {@code file} URI's.
+ * Instances of the class `FileUriResolver` resolve `file` URI's.
  * @coverage dart.engine.source
  */
 class FileUriResolver extends UriResolver {
 
   /**
-   * The name of the {@code file} scheme.
+   * The name of the `file` scheme.
    */
   static String FILE_SCHEME = "file";
 
   /**
-   * Return {@code true} if the given URI is a {@code file} URI.
+   * Return `true` if the given URI is a `file` URI.
    * @param uri the URI being tested
-   * @return {@code true} if the given URI is a {@code file} URI
+   * @return `true` if the given URI is a `file` URI
    */
   static bool isFileUri(Uri uri) => uri.scheme == FILE_SCHEME;
   Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) {
diff --git a/pkg/analyzer_experimental/lib/src/generated/utilities_dart.dart b/pkg/analyzer_experimental/lib/src/generated/utilities_dart.dart
index 80804cd..0a331cb 100644
--- a/pkg/analyzer_experimental/lib/src/generated/utilities_dart.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/utilities_dart.dart
@@ -2,7 +2,7 @@
 // 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
+ * The enumeration `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.
  * @coverage dart.engine.utilities
@@ -26,17 +26,17 @@
 
   /**
    * Initialize a newly created kind with the given state.
-   * @param isOptional {@code true} if this is an optional parameter
+   * @param isOptional `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
+   * Return `true` if this is an optional parameter.
+   * @return `true` if this is an optional parameter
    */
-  bool isOptional() => _isOptional2;
+  bool get isOptional => _isOptional2;
   int compareTo(ParameterKind other) => ordinal - other.ordinal;
   int get hashCode => ordinal;
   String toString() => name;
diff --git a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
index 72288144..410d5b0 100644
--- a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
@@ -83,22 +83,23 @@
 class CodeFormatterImpl implements CodeFormatter, AnalysisErrorListener {
 
   final FormatterOptions options;
-  final List<AnalysisError> errors = <AnalysisError>[];
+  final EditRecorder recorder;
+  final errors = <AnalysisError>[];
 
-  CodeFormatterImpl(this.options);
+  CodeFormatterImpl(FormatterOptions options) : this.options = options,
+      recorder = new EditRecorder(options);
 
   String format(CodeKind kind, String source, {int offset, int end,
       int indentationLevel:0}) {
 
     var start = tokenize(source);
-    _checkForErrors();
+    checkForErrors();
 
     var node = parse(kind, start);
-    _checkForErrors();
+    checkForErrors();
 
-    // To be continued...
-
-    return source;
+    var formatter = new FormattingEngine(options);
+    return formatter.format(source, node, start, kind, recorder);
   }
 
   ASTNode parse(CodeKind kind, Token start) {
@@ -115,7 +116,7 @@
     throw new FormatterException('Unsupported format kind: $kind');
   }
 
-  _checkForErrors() {
+  checkForErrors() {
     if (errors.length > 0) {
       throw new FormatterException.forError(errors);
     }
@@ -132,18 +133,13 @@
 
 }
 
-/// Placeholder class to hold a reference to the Class object representing
-/// the Dart keyword void.
-class Void extends Object {
-
-}
-
 
 /// Records a sequence of edits to a source string that will cause the string
 /// to be formatted when applied.
 class EditRecorder {
 
   final FormatterOptions options;
+  final EditStore editStore;
 
   int column = 0;
 
@@ -152,12 +148,105 @@
 
   Token currentToken;
 
-  int indentationLevel = 0;
   int numberOfIndentations = 0;
 
-  bool isIndentNeeded = false;
+  bool needsIndent = false;
 
-  EditRecorder(this.options);
+  EditRecorder(this.options): editStore = new EditStore();
+
+  /// Add an [Edit] that describes a textual [replacement] of a text
+  /// interval starting at the given [offset] spanning the given [length].
+  void addEdit(int offset, int length, String replacement) {
+    editStore.addEdit(offset, length, replacement);
+  }
+
+  /// Advance past the given expected [token] (or fail if not matched).
+  void advance(Token token) {
+    if (currentToken.lexeme == token.lexeme) {
+
+      // TODO(pquitslund) emit comments
+//      if (needsIndent) {
+//        advanceIndent();
+//        needsIndent = false;
+//      }
+      // Record writing a token at the current edit location
+      advanceChars(token.length);
+      currentToken = currentToken.next;
+    } else {
+      wrongToken(token.lexeme);
+    }
+  }
+
+  /// Move indices past indent, adding an edit if needed to adjust indentation
+  void advanceIndent() {
+//    var indentWidth = options.indentPerLevel * indentationLevel;
+//    var indentString = getIndentString(indentWidth);
+//    var sourceIndentWidth = 0;
+//    for (var i = 0; i < source.length; i++) {
+//      if (isIndentChar(source[sourceIndex + i])) {
+//        sourceIndentWidth += 1;
+//      } else {
+//        break;
+//      }
+//    }
+//    var hasSameIndent = sourceIndentWidth == indentWidth;
+//    if (hasSameIndent) {
+//      for (var i = 0; i < indentWidth; i++) {
+//        if (source[sourceIndex + i] != indentString[i]) {
+//          hasSameIndent = false;
+//          break;
+//        }
+//      }
+//      if (hasSameIndent) {
+//        advanceChars(indentWidth);
+//        return;
+//      }
+//    }
+//    addEdit(sourceIndex, sourceIndentWidth, indentString);
+//    column += indentWidth;
+//    sourceIndex += sourceIndentWidth;
+
+    var indent = options.indentPerLevel * numberOfIndentations;
+
+    spaces(indent);
+  }
+
+  String getIndentString(int indentWidth) {
+
+    // TODO(pquitslund) a temporary workaround
+    if (indentWidth < 0) {
+      return '';
+    }
+
+    // TODO(pquitslund) allow indent with tab chars
+
+    // Fetch a precomputed indent string
+    if (indentWidth < SPACES.length) {
+      return SPACES[indentWidth];
+    }
+
+    // Build un-precomputed strings dynamically
+    var sb = new StringBuffer();
+    for (var i = 0; i < indentWidth; ++i) {
+      sb.write(' ');
+    }
+    return sb.toString();
+  }
+
+  /// Advance past the given expected [token] (or fail if not matched).
+  void advanceToken(String token) {
+    if (currentToken.lexeme == token) {
+      advance(currentToken);
+    } else {
+      wrongToken(token);
+    }
+  }
+
+  /// Advance [column] and [sourceIndex] indices by [len] characters.
+  void advanceChars(int len) {
+    column += len;
+    sourceIndex += len;
+  }
 
   /// Count the number of whitespace chars beginning at the current
   /// [sourceIndex].
@@ -173,9 +262,8 @@
     return count;
   }
 
-  /// Indent.
+  /// Update indent indices.
   void indent() {
-    indentationLevel += options.indentPerLevel;
     numberOfIndentations++;
   }
 
@@ -192,9 +280,89 @@
     return true;
   }
 
+  /// Newline.
+  void newline() {
+    // TODO(pquitslund) emit comments
+    needsIndent = true;
+    // If there is a newline before the edit location, do nothing.
+    if (isNewlineAt(sourceIndex - NEW_LINE.length)) {
+      return;
+    }
+    // If there is a newline after the edit location, advance over it.
+    if (isNewlineAt(sourceIndex)) {
+      advanceChars(NEW_LINE.length);
+      return;
+    }
+    // Otherwise, replace whitespace with a newline.
+    var charsToReplace = countWhitespace();
+    if (isNewlineAt(sourceIndex + charsToReplace)) {
+      charsToReplace += NEW_LINE.length;
+    }
+    addEdit(sourceIndex, charsToReplace, NEW_LINE);
+    advanceChars(charsToReplace);
+  }
+
+
+  /// Un-indent.
+  void unindent() {
+    numberOfIndentations--;
+  }
+
+  /// Space.
+  void space() {
+    // TODO(pquitslund) emit comments
+//    // If there is a space before the edit location, do nothing.
+//    if (isSpaceAt(sourceIndex - 1)) {
+//      return;
+//    }
+//    // If there is a space after the edit location, advance over it.
+//    if (isSpaceAt(sourceIndex)) {
+//      advance(1);
+//      return;
+//    }
+    // Otherwise, replace spaces with a single space.
+    spaces(1);
+  }
+
+  /// Spaces.
+  void spaces(int num) {
+    var charsToReplace = countWhitespace();
+    addEdit(sourceIndex, charsToReplace, SPACES[num]);
+    advanceChars(charsToReplace);
+  }
+
+  wrongToken(String token) {
+    throw new FormatterException('expected token: "${token}", '
+                                 'actual: "${currentToken}"');
+  }
+
+  String toString() =>
+      new EditOperation().apply(editStore.edits,
+                                source.substring(0, sourceIndex));
+
 }
 
 const SPACE = ' ';
+final SPACES = [
+          '',
+          ' ',
+          '  ',
+          '   ',
+          '    ',
+          '     ',
+          '      ',
+          '       ',
+          '        ',
+          '         ',
+          '          ',
+          '           ',
+          '            ',
+          '             ',
+          '              ',
+          '               ',
+          '                ',
+];
+
 
 bool isIndentChar(String ch) => ch == SPACE; // TODO(pquitslund) also check tab
 
@@ -202,6 +370,8 @@
 /// Manages stored [Edit]s.
 class EditStore {
 
+  const EditStore();
+
   /// The underlying sequence of [Edit]s.
   final edits = <Edit>[];
 
@@ -239,7 +409,6 @@
 }
 
 
-
 /// Describes a text edit.
 class Edit {
 
@@ -264,11 +433,155 @@
 
 }
 
+/// Applies a sequence of [edits] to a [document].
+class EditOperation {
+
+  String apply(List<Edit> edits, String document) {
+
+    var edit;
+    for (var i = edits.length - 1; i >= 0; --i) {
+      edit = edits[i];
+      document = replace(document, edit.offset,
+                         edit.offset + edit.length, edit.replacement);
+    }
+
+    return document;
+  }
+
+}
+
+
+String replace(String str, int start, int end, String replacement) =>
+    str.substring(0, start) + replacement + str.substring(end);
+
+
 /// An AST visitor that drives formatting heuristics.
-class FormattingEngine extends RecursiveASTVisitor<Void> {
+class FormattingEngine extends RecursiveASTVisitor {
 
   final FormatterOptions options;
 
+  CodeKind kind;
+  EditRecorder recorder;
+
   FormattingEngine(this.options);
 
+  String format(String source, ASTNode node, Token start, CodeKind kind,
+      EditRecorder recorder) {
+
+    this.kind = kind;
+    this.recorder = recorder;
+
+    recorder..source = source
+            ..currentToken = start;
+
+    node.accept(this);
+
+    var editor = new EditOperation();
+    return editor.apply(recorder.editStore.edits, source);
+  }
+
+
+  visitClassDeclaration(ClassDeclaration node) {
+
+    recorder.advanceIndent();
+
+    if (node.documentationComment != null) {
+      node.documentationComment.accept(this);
+    }
+
+    recorder..advance(node.classKeyword)..space();
+
+    node.name.accept(this);
+
+    if (node.typeParameters != null) {
+      node.typeParameters.accept(this);
+    }
+    recorder.space();
+
+    if (node.extendsClause != null) {
+      node.extendsClause.accept(this);
+      recorder.space();
+    }
+
+    if (node.implementsClause != null) {
+      node.implementsClause.accept(this);
+      recorder.space();
+    }
+
+    recorder..advance(node.leftBracket)
+            ..indent();
+
+    for (var member in node.members) {
+      recorder..newline()
+              ..advanceIndent();
+      member.accept(this);
+    }
+
+    recorder..unindent()
+            ..newline()
+            ..advanceIndent()
+            ..advance(node.rightBracket);
+  }
+
+
+  visitBlockFunctionBody(BlockFunctionBody node) {
+    node.block.accept(this);
+  }
+
+
+  visitBlock(Block block) {
+    recorder..advance(block.leftBracket)
+            ..indent()
+            ..newline();
+    // ...
+    recorder..unindent()
+            ..advanceIndent()
+            ..advance(block.rightBracket);
+  }
+
+
+  visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    recorder..advance(node.functionDefinition)
+            ..indent()
+            ..newline();
+    node.expression.accept(this);
+    recorder..unindent()
+            ..advanceIndent()
+            ..advance(node.semicolon);
+  }
+
+
+  visitMethodDeclaration(MethodDeclaration node) {
+
+    if (node.modifierKeyword != null) {
+      recorder.advance(node.modifierKeyword);
+      recorder.space();
+    }
+
+    if (node.returnType != null) {
+      node.returnType.accept(this);
+      recorder.space();
+    }
+
+    recorder.advance(node.name.beginToken);
+
+    node.parameters.accept(this);
+
+    recorder.space();
+
+    node.body.accept(this);
+  }
+
+
+  visitFormalParameterList(FormalParameterList node) {
+    recorder.advance(node.beginToken);
+    //...
+    recorder.advance(node.endToken);
+  }
+
+
+  visitSimpleIdentifier(SimpleIdentifier node) {
+    recorder.advance(node.token);
+  }
+
 }
diff --git a/pkg/analyzer_experimental/lib/src/services/runtime/coverage/coverage_impl.dart b/pkg/analyzer_experimental/lib/src/services/runtime/coverage/coverage_impl.dart
index bc6b7cf..f747ce6 100644
--- a/pkg/analyzer_experimental/lib/src/services/runtime/coverage/coverage_impl.dart
+++ b/pkg/analyzer_experimental/lib/src/services/runtime/coverage/coverage_impl.dart
@@ -193,7 +193,7 @@
   String rewritePathContent(String path) {
     if (path.endsWith('__coverage_lib.dart')) {
       String implPath = pathos.joinAll([
-          pathos.dirname(new Options().script),
+          pathos.dirname(Platform.script),
           '..', 'lib', 'src', 'services', 'runtime', 'coverage',
           'coverage_lib.dart']);
       var content = new File(implPath).readAsStringSync();
diff --git a/pkg/analyzer_experimental/test/generated/ast_test.dart b/pkg/analyzer_experimental/test/generated/ast_test.dart
index ae71ad1b..bd06fba 100644
--- a/pkg/analyzer_experimental/test/generated/ast_test.dart
+++ b/pkg/analyzer_experimental/test/generated/ast_test.dart
@@ -212,11 +212,11 @@
   }
 }
 /**
- * The class {@code ASTFactory} defines utility methods that can be used to create AST nodes. The
+ * The class `ASTFactory` defines utility methods that can be used to create AST nodes. The
  * nodes that are created are complete in the sense that all of the tokens that would have been
  * associated with the nodes by a parser are also created, but the token stream is not constructed.
  * None of the nodes are resolved.
- * <p>
+ *
  * The general pattern is for the name of the factory method to be the same as the name of the class
  * of AST node being created. There are two notable exceptions. The first is for methods creating
  * nodes that are part of a cascade expression. These methods are all prefixed with 'cascaded'. The
@@ -402,7 +402,7 @@
   /**
    * Create a type name whose name has been resolved to the given element and whose type has been
    * resolved to the type of the given element.
-   * <p>
+   *
    * <b>Note:</b> This method does not correctly handle class elements that have type parameters.
    * @param element the element defining the type represented by the type name
    * @return the type name that was created
@@ -1950,7 +1950,7 @@
   }
 
   /**
-   * Assert that a {@code ToSourceVisitor} will produce the expected source when visiting the given
+   * Assert that a `ToSourceVisitor` will produce the expected source when visiting the given
    * node.
    * @param expectedSource the source string that the visitor is expected to produce
    * @param node the AST node being visited to produce the actual source
diff --git a/pkg/analyzer_experimental/test/generated/element_test.dart b/pkg/analyzer_experimental/test/generated/element_test.dart
index a89b723..4625b78 100644
--- a/pkg/analyzer_experimental/test/generated/element_test.dart
+++ b/pkg/analyzer_experimental/test/generated/element_test.dart
@@ -347,6 +347,7 @@
     String getterName = "g";
     PropertyAccessorElement getterG = ElementFactory.getterElement(getterName, false, typeE);
     classA.accessors = <PropertyAccessorElement> [getterG];
+    ((getterG.type as FunctionTypeImpl)).typeArguments = classA.type.typeArguments;
     InterfaceType typeI = ElementFactory.classElement2("I", []).type;
     InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(classA);
     typeAI.typeArguments = <Type2> [typeI];
@@ -588,6 +589,7 @@
     String methodName = "m";
     MethodElementImpl methodM = ElementFactory.methodElement(methodName, typeE, [typeE]);
     classA.methods = <MethodElement> [methodM];
+    ((methodM.type as FunctionTypeImpl)).typeArguments = classA.type.typeArguments;
     InterfaceType typeI = ElementFactory.classElement2("I", []).type;
     InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(classA);
     typeAI.typeArguments = <Type2> [typeI];
@@ -650,6 +652,7 @@
     String setterName = "s";
     PropertyAccessorElement setterS = ElementFactory.setterElement(setterName, false, typeE);
     classA.accessors = <PropertyAccessorElement> [setterS];
+    ((setterS.type as FunctionTypeImpl)).typeArguments = classA.type.typeArguments;
     InterfaceType typeI = ElementFactory.classElement2("I", []).type;
     InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(classA);
     typeAI.typeArguments = <Type2> [typeI];
@@ -1023,6 +1026,7 @@
     String methodName = "m";
     MethodElementImpl methodM = ElementFactory.methodElement(methodName, typeE, [typeE]);
     classA.methods = <MethodElement> [methodM];
+    ((methodM.type as FunctionTypeImpl)).typeArguments = classA.type.typeArguments;
     ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
     InterfaceType typeB = classB.type;
     InterfaceTypeImpl typeAF = new InterfaceTypeImpl.con1(classA);
@@ -1555,7 +1559,7 @@
   }
 }
 /**
- * The class {@code ElementFactory} defines utility methods used to create elements for testing
+ * The class `ElementFactory` defines utility methods used to create elements for testing
  * purposes. The elements that are created are complete in the sense that as much of the element
  * model as can be created, given the provided information, has been created.
  */
@@ -1586,12 +1590,11 @@
     return element;
   }
   static ClassElementImpl classElement2(String typeName, List<String> parameterNames) => classElement(typeName, object.type, parameterNames);
-  static ConstructorElementImpl constructorElement(ClassElement clazz, String name) {
-    Type2 type = clazz.type;
+  static ConstructorElementImpl constructorElement(ClassElement definingClass, String name) {
+    Type2 type = definingClass.type;
     ConstructorElementImpl constructor = new ConstructorElementImpl(name == null ? null : ASTFactory.identifier3(name));
+    constructor.returnType = type;
     FunctionTypeImpl constructorType = new FunctionTypeImpl.con1(constructor);
-    constructorType.normalParameterTypes = <Type2> [type];
-    constructorType.returnType = type;
     constructor.type = constructorType;
     return constructor;
   }
@@ -1612,9 +1615,9 @@
     getter.static = isStatic;
     getter.synthetic = true;
     getter.variable = field;
+    getter.returnType = type2;
     field.getter = getter;
     FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
-    getterType.returnType = type2;
     getter.type = getterType;
     if (!isConst && !isFinal) {
       PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(field);
@@ -1622,10 +1625,10 @@
       setter.static = isStatic;
       setter.synthetic = true;
       setter.variable = field;
+      setter.returnType = VoidTypeImpl.instance;
       field.setter = setter;
       FunctionTypeImpl setterType = new FunctionTypeImpl.con1(getter);
       setterType.normalParameterTypes = <Type2> [type2];
-      setterType.returnType = VoidTypeImpl.instance;
       setter.type = setterType;
     }
     return field;
@@ -1637,8 +1640,10 @@
     FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier3(functionName));
     FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
     functionElement.type = functionType;
-    if (returnElement != null) {
-      functionType.returnType = returnElement.type;
+    if (returnElement == null) {
+      functionElement.returnType = VoidTypeImpl.instance;
+    } else {
+      functionElement.returnType = returnElement.type;
     }
     int normalCount = normalParameters == null ? 0 : normalParameters.length;
     if (normalCount > 0) {
@@ -1676,8 +1681,10 @@
     FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier3(functionName));
     FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
     functionElement.type = functionType;
-    if (returnElement != null) {
-      functionType.returnType = returnElement.type;
+    if (returnElement == null) {
+      functionElement.returnType = VoidTypeImpl.instance;
+    } else {
+      functionElement.returnType = returnElement.type;
     }
     int count = normalParameters == null ? 0 : normalParameters.length;
     if (count > 0) {
@@ -1716,9 +1723,9 @@
     getter.getter = true;
     getter.static = isStatic;
     getter.variable = field;
+    getter.returnType = type2;
     field.getter = getter;
     FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
-    getterType.returnType = type2;
     getter.type = getterType;
     return getter;
   }
@@ -1751,9 +1758,9 @@
       parameters[i] = parameter;
     }
     method.parameters = parameters;
+    method.returnType = returnType2;
     FunctionTypeImpl methodType = new FunctionTypeImpl.con1(method);
     methodType.normalParameterTypes = argumentTypes;
-    methodType.returnType = returnType2;
     method.type = methodType;
     return method;
   }
@@ -1782,19 +1789,19 @@
     getter.getter = true;
     getter.static = isStatic;
     getter.variable = field;
+    getter.returnType = type2;
     field.getter = getter;
     FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
-    getterType.returnType = type2;
     getter.type = getterType;
     PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(field);
     setter.setter = true;
     setter.static = isStatic;
     setter.synthetic = true;
     setter.variable = field;
+    setter.returnType = VoidTypeImpl.instance;
     field.setter = setter;
-    FunctionTypeImpl setterType = new FunctionTypeImpl.con1(getter);
+    FunctionTypeImpl setterType = new FunctionTypeImpl.con1(setter);
     setterType.normalParameterTypes = <Type2> [type2];
-    setterType.returnType = VoidTypeImpl.instance;
     setter.type = setterType;
     return setter;
   }
@@ -1808,9 +1815,9 @@
     getter.static = true;
     getter.synthetic = true;
     getter.variable = variable;
+    getter.returnType = type2;
     variable.getter = getter;
     FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
-    getterType.returnType = type2;
     getter.type = getterType;
     if (!isFinal) {
       PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(variable);
@@ -1818,10 +1825,10 @@
       setter.static = true;
       setter.synthetic = true;
       setter.variable = variable;
+      setter.returnType = VoidTypeImpl.instance;
       variable.setter = setter;
       FunctionTypeImpl setterType = new FunctionTypeImpl.con1(getter);
       setterType.normalParameterTypes = <Type2> [type2];
-      setterType.returnType = VoidTypeImpl.instance;
       setter.type = setterType;
     }
     return variable;
@@ -2207,9 +2214,12 @@
     EngineTestCase.assertLength(0, types);
   }
   void test_getReturnType() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier3("f")));
+    Type2 expectedReturnType = VoidTypeImpl.instance;
+    FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier3("f"));
+    functionElement.returnType = expectedReturnType;
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(functionElement);
     Type2 returnType = type.returnType;
-    JUnitTestCase.assertEquals(VoidTypeImpl.instance, returnType);
+    JUnitTestCase.assertEquals(expectedReturnType, returnType);
   }
   void test_getTypeArguments() {
     FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier3("f")));
@@ -2420,15 +2430,15 @@
     variableS.bound = stringType;
     TypeVariableTypeImpl typeS = new TypeVariableTypeImpl(variableS);
     FunctionElementImpl functionAliasElement = new FunctionElementImpl.con1(ASTFactory.identifier3("func"));
+    functionAliasElement.returnType = stringType;
     FunctionTypeImpl functionAliasType = new FunctionTypeImpl.con1(functionAliasElement);
     functionAliasElement.type = functionAliasType;
-    functionAliasType.returnType = stringType;
     functionAliasType.normalParameterTypes = <Type2> [typeB];
     functionAliasType.optionalParameterTypes = <Type2> [typeS];
     FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier3("f"));
+    functionElement.returnType = provider.dynamicType;
     FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
     functionElement.type = functionType;
-    functionType.returnType = provider.dynamicType;
     functionType.normalParameterTypes = <Type2> [boolType];
     functionType.optionalParameterTypes = <Type2> [stringType];
     JUnitTestCase.assertTrue(functionType.isAssignableTo(functionAliasType));
@@ -2463,26 +2473,33 @@
     JUnitTestCase.assertEquals(expectedTypes, types);
   }
   void test_setReturnType() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier3("f")));
     Type2 expectedType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier3("C")));
-    type.returnType = expectedType;
-    Type2 returnType = type.returnType;
-    JUnitTestCase.assertEquals(expectedType, returnType);
+    FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier3("f"));
+    functionElement.returnType = expectedType;
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(functionElement);
+    JUnitTestCase.assertEquals(expectedType, type.returnType);
   }
   void test_setTypeArguments() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier3("f")));
-    Type2 expectedType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier3("C")));
+    ClassElementImpl enclosingClass = ElementFactory.classElement2("C", ["E"]);
+    MethodElementImpl methodElement = new MethodElementImpl.con1(ASTFactory.identifier3("m"));
+    enclosingClass.methods = <MethodElement> [methodElement];
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(methodElement);
+    Type2 expectedType = enclosingClass.typeVariables[0].type;
     type.typeArguments = <Type2> [expectedType];
     List<Type2> arguments = type.typeArguments;
     EngineTestCase.assertLength(1, arguments);
     JUnitTestCase.assertEquals(expectedType, arguments[0]);
   }
   void test_substitute2_equal() {
-    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier3("f")));
-    TypeVariableTypeImpl parameterType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier3("E")));
-    functionType.returnType = parameterType;
+    ClassElementImpl definingClass = ElementFactory.classElement2("C", ["E"]);
+    TypeVariableType parameterType = definingClass.typeVariables[0].type;
+    MethodElementImpl functionElement = new MethodElementImpl.con1(ASTFactory.identifier3("m"));
+    functionElement.returnType = parameterType;
+    definingClass.methods = <MethodElement> [functionElement];
+    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
     functionType.normalParameterTypes = <Type2> [parameterType];
     functionType.optionalParameterTypes = <Type2> [parameterType];
+    functionType.typeArguments = <Type2> [parameterType];
     LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
     String namedParameterName = "c";
     namedParameterTypes[namedParameterName] = parameterType;
@@ -2501,12 +2518,13 @@
     JUnitTestCase.assertEquals(argumentType, namedParameters[namedParameterName]);
   }
   void test_substitute2_notEqual() {
-    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier3("f")));
     Type2 returnType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier3("R")));
     Type2 normalParameterType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier3("A")));
     Type2 optionalParameterType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier3("B")));
     Type2 namedParameterType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier3("C")));
-    functionType.returnType = returnType;
+    FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier3("f"));
+    functionElement.returnType = returnType;
+    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
     functionType.normalParameterTypes = <Type2> [normalParameterType];
     functionType.optionalParameterTypes = <Type2> [optionalParameterType];
     LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
@@ -2714,7 +2732,7 @@
 }
 class InterfaceTypeImpl_18 extends InterfaceTypeImpl {
   InterfaceTypeImpl_18(ClassElement arg0) : super.con1(arg0);
-  bool isDartCoreFunction() => true;
+  bool get isDartCoreFunction => true;
 }
 main() {
   ElementKindTest.dartSuite();
diff --git a/pkg/analyzer_experimental/test/generated/parser_test.dart b/pkg/analyzer_experimental/test/generated/parser_test.dart
index 9c5f3d8..41f6646 100644
--- a/pkg/analyzer_experimental/test/generated/parser_test.dart
+++ b/pkg/analyzer_experimental/test/generated/parser_test.dart
@@ -16,11 +16,11 @@
 import 'scanner_test.dart' show TokenFactory;
 import 'ast_test.dart' show ASTFactory;
 /**
- * The class {@code SimpleParserTest} defines parser tests that test individual parsing method. The
+ * The class `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}.
+ *
+ * More complex tests should be defined in the class [ComplexParserTest].
  */
 class SimpleParserTest extends ParserTestCase {
   void fail_parseCommentReference_this() {
@@ -83,11 +83,11 @@
   }
   void test_createSyntheticIdentifier() {
     SimpleIdentifier identifier = createSyntheticIdentifier();
-    JUnitTestCase.assertTrue(identifier.isSynthetic());
+    JUnitTestCase.assertTrue(identifier.isSynthetic);
   }
   void test_createSyntheticStringLiteral() {
     SimpleStringLiteral literal = createSyntheticStringLiteral();
-    JUnitTestCase.assertTrue(literal.isSynthetic());
+    JUnitTestCase.assertTrue(literal.isSynthetic);
   }
   void test_isFunctionDeclaration_nameButNoReturn_block() {
     JUnitTestCase.assertTrue(isFunctionDeclaration("f() {}"));
@@ -1508,15 +1508,15 @@
   }
   void test_parseDocumentationComment_block() {
     Comment comment = ParserTestCase.parse5("parseDocumentationComment", "/** */ class", []);
-    JUnitTestCase.assertFalse(comment.isBlock());
-    JUnitTestCase.assertTrue(comment.isDocumentation());
-    JUnitTestCase.assertFalse(comment.isEndOfLine());
+    JUnitTestCase.assertFalse(comment.isBlock);
+    JUnitTestCase.assertTrue(comment.isDocumentation);
+    JUnitTestCase.assertFalse(comment.isEndOfLine);
   }
   void test_parseDocumentationComment_block_withReference() {
     Comment comment = ParserTestCase.parse5("parseDocumentationComment", "/** [a] */ class", []);
-    JUnitTestCase.assertFalse(comment.isBlock());
-    JUnitTestCase.assertTrue(comment.isDocumentation());
-    JUnitTestCase.assertFalse(comment.isEndOfLine());
+    JUnitTestCase.assertFalse(comment.isBlock);
+    JUnitTestCase.assertTrue(comment.isDocumentation);
+    JUnitTestCase.assertFalse(comment.isEndOfLine);
     NodeList<CommentReference> references = comment.references;
     EngineTestCase.assertSize(1, references);
     CommentReference reference = references[0];
@@ -1525,9 +1525,9 @@
   }
   void test_parseDocumentationComment_endOfLine() {
     Comment comment = ParserTestCase.parse5("parseDocumentationComment", "/// \n/// \n class", []);
-    JUnitTestCase.assertFalse(comment.isBlock());
-    JUnitTestCase.assertTrue(comment.isDocumentation());
-    JUnitTestCase.assertFalse(comment.isEndOfLine());
+    JUnitTestCase.assertFalse(comment.isBlock);
+    JUnitTestCase.assertTrue(comment.isDocumentation);
+    JUnitTestCase.assertFalse(comment.isEndOfLine);
   }
   void test_parseDoStatement() {
     DoStatement statement = ParserTestCase.parse5("parseDoStatement", "do {} while (x);", []);
@@ -2870,7 +2870,7 @@
   }
   void test_parsePrimaryExpression_string() {
     SimpleStringLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "\"string\"", []);
-    JUnitTestCase.assertFalse(literal.isMultiline());
+    JUnitTestCase.assertFalse(literal.isMultiline);
     JUnitTestCase.assertEquals("string", literal.value);
   }
   void test_parsePrimaryExpression_super() {
@@ -3668,7 +3668,7 @@
   }
 
   /**
-   * Invoke the method {@link Parser#computeStringValue(String)} with the given argument.
+   * Invoke the method [Parser#computeStringValue] 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
@@ -3680,7 +3680,7 @@
   }
 
   /**
-   * Invoke the method {@link Parser#createSyntheticIdentifier()} with the parser set to the token
+   * Invoke the method [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
@@ -3692,7 +3692,7 @@
   }
 
   /**
-   * Invoke the method {@link Parser#createSyntheticIdentifier()} with the parser set to the token
+   * Invoke the method [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
@@ -3704,7 +3704,7 @@
   }
 
   /**
-   * Invoke the method {@link Parser#isFunctionDeclaration()} with the parser set to the token
+   * Invoke the method [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
@@ -3716,7 +3716,7 @@
   }
 
   /**
-   * Invoke the method {@link Parser#isFunctionExpression()} with the parser set to the token stream
+   * Invoke the method [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
@@ -3731,7 +3731,7 @@
   }
 
   /**
-   * Invoke the method {@link Parser#isInitializedVariableDeclaration()} with the parser set to the
+   * Invoke the method [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
@@ -3743,7 +3743,7 @@
   }
 
   /**
-   * Invoke the method {@link Parser#isSwitchMember()} with the parser set to the token stream
+   * Invoke the method [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
@@ -3755,13 +3755,13 @@
   }
 
   /**
-   * Invoke a "skip" method in {@link Parser}. The method is assumed to take a token as it's
+   * Invoke a "skip" method in [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}
+   * @throws AssertionFailedError if the result is `null`
    */
   Token skip(String methodName, String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
@@ -5853,11 +5853,11 @@
   }
 }
 /**
- * The class {@code ComplexParserTest} defines parser tests that test the parsing of more complex
+ * The class `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}.
+ *
+ * Simpler tests should be defined in the class [SimpleParserTest].
  */
 class ComplexParserTest extends ParserTestCase {
   void test_additiveExpression_normal() {
@@ -5979,7 +5979,7 @@
       Expression lhs = ((section as AssignmentExpression)).leftHandSide;
       EngineTestCase.assertInstanceOf(IndexExpression, lhs);
       IndexExpression index = lhs as IndexExpression;
-      JUnitTestCase.assertTrue(index.isCascaded());
+      JUnitTestCase.assertTrue(index.isCascaded);
       JUnitTestCase.assertSame(target, index.realTarget);
     }
   }
@@ -6263,7 +6263,7 @@
   }
 }
 /**
- * Instances of the class {@code ASTValidator} are used to validate the correct construction of an
+ * Instances of the class `ASTValidator` are used to validate the correct construction of an
  * AST structure.
  */
 class ASTValidator extends GeneralizingASTVisitor<Object> {
@@ -6340,9 +6340,9 @@
   static List<Object> _EMPTY_ARGUMENTS = new List<Object>(0);
 
   /**
-   * Invoke a parse method in {@link Parser}. The method is assumed to have the given number and
+   * Invoke a parse method in [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
@@ -6350,14 +6350,14 @@
    * @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
+   * @throws AssertionFailedError if the result is `null` or if any errors are produced
    */
   static Object parse(String methodName, List<Object> objects, String source) => parse3(methodName, objects, source, new List<AnalysisError>(0));
 
   /**
-   * Invoke a parse method in {@link Parser}. The method is assumed to have the given number and
+   * Invoke a parse method in [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
@@ -6366,7 +6366,7 @@
    * @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
+   * @throws AssertionFailedError if the result is `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<AnalysisError> errors) {
@@ -6377,9 +6377,9 @@
   }
 
   /**
-   * Invoke a parse method in {@link Parser}. The method is assumed to have the given number and
+   * Invoke a parse method in [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
@@ -6388,7 +6388,7 @@
    * @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
+   * @throws AssertionFailedError if the result is `null` or the errors produced while
    * scanning and parsing the source do not match the expected errors
    */
   static Object parse4(String methodName, List<Object> objects, String source, List<ErrorCode> errorCodes) {
@@ -6399,8 +6399,8 @@
   }
 
   /**
-   * Invoke a parse method in {@link Parser}. The method is assumed to have no arguments.
-   * <p>
+   * Invoke a parse method in [Parser]. The method is assumed to have no arguments.
+   *
    * 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
@@ -6408,7 +6408,7 @@
    * @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
+   * @throws AssertionFailedError if the result is `null` or the errors produced while
    * scanning and parsing the source do not match the expected errors
    */
   static Object parse5(String methodName, String source, List<ErrorCode> errorCodes) => parse4(methodName, _EMPTY_ARGUMENTS, source, errorCodes);
@@ -6419,7 +6419,7 @@
    * @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}
+   * not match those that are expected, or if the result would have been `null`
    */
   static CompilationUnit parseCompilationUnit(String source, List<ErrorCode> errorCodes) {
     GatheringErrorListener listener = new GatheringErrorListener();
@@ -6439,7 +6439,7 @@
    * @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}
+   * not match those that are expected, or if the result would have been `null`
    */
   static Expression parseExpression(String source, List<ErrorCode> errorCodes) {
     GatheringErrorListener listener = new GatheringErrorListener();
@@ -6459,7 +6459,7 @@
    * @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}
+   * not match those that are expected, or if the result would have been `null`
    */
   static Statement parseStatement(String source, List<ErrorCode> errorCodes) {
     GatheringErrorListener listener = new GatheringErrorListener();
@@ -6481,7 +6481,7 @@
    * @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}
+   * are expected, or if the result would have been `null`
    */
   static List<Statement> parseStatements(String source, int expectedCount, List<ErrorCode> errorCodes) {
     GatheringErrorListener listener = new GatheringErrorListener();
@@ -6496,9 +6496,9 @@
   }
 
   /**
-   * Invoke a method in {@link Parser}. The method is assumed to have the given number and type of
+   * Invoke a method in [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
@@ -6507,7 +6507,7 @@
    * @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
+   * @throws AssertionFailedError if the result is `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) {
@@ -6523,8 +6523,8 @@
   }
 
   /**
-   * Invoke a method in {@link Parser}. The method is assumed to have no arguments.
-   * <p>
+   * Invoke a method in [Parser]. The method is assumed to have no arguments.
+   *
    * 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
@@ -6532,7 +6532,7 @@
    * @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
+   * @throws AssertionFailedError if the result is `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, _EMPTY_ARGUMENTS, source, listener);
@@ -6562,7 +6562,7 @@
   }
 }
 /**
- * The class {@code RecoveryParserTest} defines parser tests that test the parsing of invalid code
+ * The class `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 {
@@ -6572,24 +6572,24 @@
   void test_additiveExpression_missing_LHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("+ y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
   }
   void test_additiveExpression_missing_LHS_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("+", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_additiveExpression_missing_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("x +", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_additiveExpression_missing_RHS_super() {
     BinaryExpression expression = ParserTestCase.parseExpression("super +", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_additiveExpression_precedence_multiplicative_left() {
     BinaryExpression expression = ParserTestCase.parseExpression("* +", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
@@ -6607,51 +6607,51 @@
     AssignmentExpression expression = ParserTestCase.parseExpression("= y = 0", [ParserErrorCode.MISSING_IDENTIFIER]);
     Expression syntheticExpression = expression.leftHandSide;
     EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
-    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic);
   }
   void test_assignmentExpression_missing_compound2() {
     AssignmentExpression expression = ParserTestCase.parseExpression("x = = 0", [ParserErrorCode.MISSING_IDENTIFIER]);
     Expression syntheticExpression = ((expression.rightHandSide as AssignmentExpression)).leftHandSide;
     EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
-    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic);
   }
   void test_assignmentExpression_missing_compound3() {
     AssignmentExpression expression = ParserTestCase.parseExpression("x = y =", [ParserErrorCode.MISSING_IDENTIFIER]);
     Expression syntheticExpression = ((expression.rightHandSide as AssignmentExpression)).rightHandSide;
     EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
-    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic);
   }
   void test_assignmentExpression_missing_LHS() {
     AssignmentExpression expression = ParserTestCase.parseExpression("= 0", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftHandSide);
-    JUnitTestCase.assertTrue(expression.leftHandSide.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftHandSide.isSynthetic);
   }
   void test_assignmentExpression_missing_RHS() {
     AssignmentExpression expression = ParserTestCase.parseExpression("x =", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftHandSide);
-    JUnitTestCase.assertTrue(expression.rightHandSide.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightHandSide.isSynthetic);
   }
   void test_bitwiseAndExpression_missing_LHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("& y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
   }
   void test_bitwiseAndExpression_missing_LHS_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("&", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_bitwiseAndExpression_missing_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("x &", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_bitwiseAndExpression_missing_RHS_super() {
     BinaryExpression expression = ParserTestCase.parseExpression("super &", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_bitwiseAndExpression_precedence_equality_left() {
     BinaryExpression expression = ParserTestCase.parseExpression("== &", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
@@ -6668,24 +6668,24 @@
   void test_bitwiseOrExpression_missing_LHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("| y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
   }
   void test_bitwiseOrExpression_missing_LHS_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("|", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_bitwiseOrExpression_missing_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("x |", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_bitwiseOrExpression_missing_RHS_super() {
     BinaryExpression expression = ParserTestCase.parseExpression("super |", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_bitwiseOrExpression_precedence_xor_left() {
     BinaryExpression expression = ParserTestCase.parseExpression("^ |", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
@@ -6702,24 +6702,24 @@
   void test_bitwiseXorExpression_missing_LHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("^ y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
   }
   void test_bitwiseXorExpression_missing_LHS_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("^", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_bitwiseXorExpression_missing_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("x ^", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_bitwiseXorExpression_missing_RHS_super() {
     BinaryExpression expression = ParserTestCase.parseExpression("super ^", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_bitwiseXorExpression_precedence_and_left() {
     BinaryExpression expression = ParserTestCase.parseExpression("& ^", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
@@ -6739,34 +6739,34 @@
   void test_conditionalExpression_missingElse() {
     ConditionalExpression expression = ParserTestCase.parse5("parseConditionalExpression", "x ? y :", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.elseExpression);
-    JUnitTestCase.assertTrue(expression.elseExpression.isSynthetic());
+    JUnitTestCase.assertTrue(expression.elseExpression.isSynthetic);
   }
   void test_conditionalExpression_missingThen() {
     ConditionalExpression expression = ParserTestCase.parse5("parseConditionalExpression", "x ? : z", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.thenExpression);
-    JUnitTestCase.assertTrue(expression.thenExpression.isSynthetic());
+    JUnitTestCase.assertTrue(expression.thenExpression.isSynthetic);
   }
   void test_equalityExpression_missing_LHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("== y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
   }
   void test_equalityExpression_missing_LHS_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("==", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_equalityExpression_missing_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("x ==", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_equalityExpression_missing_RHS_super() {
     BinaryExpression expression = ParserTestCase.parseExpression("super ==", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_equalityExpression_precedence_relational_left() {
     BinaryExpression expression = ParserTestCase.parseExpression("is ==", [ParserErrorCode.EXPECTED_TYPE_NAME, ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
@@ -6785,21 +6785,21 @@
     EngineTestCase.assertSize(4, result);
     Expression syntheticExpression = result[0];
     EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
-    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic);
   }
   void test_expressionList_multiple_middle() {
     List<Expression> result = ParserTestCase.parse5("parseExpressionList", "1, 2, , 4", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertSize(4, result);
     Expression syntheticExpression = result[2];
     EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
-    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic);
   }
   void test_expressionList_multiple_start() {
     List<Expression> result = ParserTestCase.parse5("parseExpressionList", "1, 2, 3,", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertSize(4, result);
     Expression syntheticExpression = result[3];
     EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
-    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic);
   }
   void test_isExpression_noType() {
     CompilationUnit unit = ParserTestCase.parseCompilationUnit("class Bar<T extends Foo> {m(x){if (x is ) return;if (x is !)}}", [ParserErrorCode.EXPECTED_TYPE_NAME, ParserErrorCode.EXPECTED_TYPE_NAME, ParserErrorCode.MISSING_STATEMENT]);
@@ -6813,25 +6813,25 @@
     JUnitTestCase.assertNotNull(expression.notOperator);
     TypeName type = expression.type;
     JUnitTestCase.assertNotNull(type);
-    JUnitTestCase.assertTrue(type.name.isSynthetic());
+    JUnitTestCase.assertTrue(type.name.isSynthetic);
     EngineTestCase.assertInstanceOf(EmptyStatement, ifStatement.thenStatement);
   }
   void test_logicalAndExpression_missing_LHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("&& y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
   }
   void test_logicalAndExpression_missing_LHS_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("&&", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_logicalAndExpression_missing_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("x &&", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_logicalAndExpression_precedence_bitwiseOr_left() {
     BinaryExpression expression = ParserTestCase.parseExpression("| &&", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
@@ -6844,19 +6844,19 @@
   void test_logicalOrExpression_missing_LHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("|| y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
   }
   void test_logicalOrExpression_missing_LHS_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("||", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_logicalOrExpression_missing_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("x ||", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_logicalOrExpression_precedence_logicalAnd_left() {
     BinaryExpression expression = ParserTestCase.parseExpression("&& ||", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
@@ -6869,24 +6869,24 @@
   void test_multiplicativeExpression_missing_LHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("* y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
   }
   void test_multiplicativeExpression_missing_LHS_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("*", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_multiplicativeExpression_missing_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("x *", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_multiplicativeExpression_missing_RHS_super() {
     BinaryExpression expression = ParserTestCase.parseExpression("super *", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_multiplicativeExpression_precedence_unary_left() {
     BinaryExpression expression = ParserTestCase.parseExpression("-x *", [ParserErrorCode.MISSING_IDENTIFIER]);
@@ -6903,25 +6903,25 @@
   void test_prefixExpression_missing_operand_minus() {
     PrefixExpression expression = ParserTestCase.parseExpression("-", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.operand);
-    JUnitTestCase.assertTrue(expression.operand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.operand.isSynthetic);
     JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type);
   }
   void test_relationalExpression_missing_LHS() {
     IsExpression expression = ParserTestCase.parseExpression("is y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.expression);
-    JUnitTestCase.assertTrue(expression.expression.isSynthetic());
+    JUnitTestCase.assertTrue(expression.expression.isSynthetic);
   }
   void test_relationalExpression_missing_LHS_RHS() {
     IsExpression expression = ParserTestCase.parseExpression("is", [ParserErrorCode.EXPECTED_TYPE_NAME, ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.expression);
-    JUnitTestCase.assertTrue(expression.expression.isSynthetic());
+    JUnitTestCase.assertTrue(expression.expression.isSynthetic);
     EngineTestCase.assertInstanceOf(TypeName, expression.type);
-    JUnitTestCase.assertTrue(expression.type.isSynthetic());
+    JUnitTestCase.assertTrue(expression.type.isSynthetic);
   }
   void test_relationalExpression_missing_RHS() {
     IsExpression expression = ParserTestCase.parseExpression("x is", [ParserErrorCode.EXPECTED_TYPE_NAME]);
     EngineTestCase.assertInstanceOf(TypeName, expression.type);
-    JUnitTestCase.assertTrue(expression.type.isSynthetic());
+    JUnitTestCase.assertTrue(expression.type.isSynthetic);
   }
   void test_relationalExpression_precedence_shift_right() {
     IsExpression expression = ParserTestCase.parseExpression("<< is", [ParserErrorCode.EXPECTED_TYPE_NAME, ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
@@ -6930,24 +6930,24 @@
   void test_shiftExpression_missing_LHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("<< y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
   }
   void test_shiftExpression_missing_LHS_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("<<", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
-    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_shiftExpression_missing_RHS() {
     BinaryExpression expression = ParserTestCase.parseExpression("x <<", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_shiftExpression_missing_RHS_super() {
     BinaryExpression expression = ParserTestCase.parseExpression("super <<", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
-    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic);
   }
   void test_shiftExpression_precedence_unary_left() {
     BinaryExpression expression = ParserTestCase.parseExpression("+ <<", [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.MISSING_IDENTIFIER]);
@@ -7282,13 +7282,13 @@
   }
 }
 /**
- * The class {@code ErrorParserTest} defines parser tests that test the parsing of code to ensure
+ * The class `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.parse4("parseListOrMapLiteral", <Object> [null], "1", [ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]);
-    JUnitTestCase.assertTrue(literal.isSynthetic());
+    JUnitTestCase.assertTrue(literal.isSynthetic);
   }
   void fail_illegalAssignmentToNonAssignable_superAssigned() {
     ParserTestCase.parseExpression("super = x;", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
@@ -7490,7 +7490,7 @@
   }
   void test_expectedStringLiteral() {
     StringLiteral expression = ParserTestCase.parse5("parseStringLiteral", "1", [ParserErrorCode.EXPECTED_STRING_LITERAL]);
-    JUnitTestCase.assertTrue(expression.isSynthetic());
+    JUnitTestCase.assertTrue(expression.isSynthetic);
   }
   void test_expectedToken_commaMissingInArgumentList() {
     ParserTestCase.parse5("parseArgumentList", "(x, y z)", [ParserErrorCode.EXPECTED_TOKEN]);
@@ -7718,7 +7718,7 @@
   }
   void test_missingIdentifier_number() {
     SimpleIdentifier expression = ParserTestCase.parse5("parseSimpleIdentifier", "1", [ParserErrorCode.MISSING_IDENTIFIER]);
-    JUnitTestCase.assertTrue(expression.isSynthetic());
+    JUnitTestCase.assertTrue(expression.isSynthetic);
   }
   void test_missingKeywordOperator() {
     ParserTestCase.parse4("parseOperator", <Object> [emptyCommentAndMetadata(), null, null], "+(x) {}", [ParserErrorCode.MISSING_KEYWORD_OPERATOR]);
@@ -7871,7 +7871,7 @@
   void test_useOfUnaryPlusOperator() {
     SimpleIdentifier expression = ParserTestCase.parse5("parseUnaryExpression", "+x", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression);
-    JUnitTestCase.assertTrue(expression.isSynthetic());
+    JUnitTestCase.assertTrue(expression.isSynthetic);
   }
   void test_varAsTypeName_as() {
     ParserTestCase.parseExpression("x as var", [ParserErrorCode.VAR_AS_TYPE_NAME]);
diff --git a/pkg/analyzer_experimental/test/generated/resolver_test.dart b/pkg/analyzer_experimental/test/generated/resolver_test.dart
index c365a79..81a1c44 100644
--- a/pkg/analyzer_experimental/test/generated/resolver_test.dart
+++ b/pkg/analyzer_experimental/test/generated/resolver_test.dart
@@ -201,7 +201,7 @@
   void test_is_subclass() {
     Source source = addSource(EngineTestCase.createSource(["class A {}", "class B extends A {", "  B m() => this;", "}", "A f(A p) {", "  if (p is B) {", "    return p.m();", "  }", "}"]));
     LibraryElement library = resolve(source);
-    assertNoErrors();
+    assertErrors([StaticTypeWarningCode.UNDEFINED_METHOD]);
     verify([source]);
     CompilationUnit unit = resolveCompilationUnit(source, library);
     FunctionDeclaration function = unit.declarations[2] as FunctionDeclaration;
@@ -953,6 +953,30 @@
     assertNoErrors();
     verify([source]);
   }
+  void test_invalidMethodOverrideNamedParamType() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  m({int a}) {}", "}", "class B implements A {", "  m({int a, int b}) {}", "}"]));
+    resolve(source);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_invalidOverrideDifferentDefaultValues_named() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  m({int p : 0}) {}", "}", "class B extends A {", "  m({int p : 0}) {}", "}"]));
+    resolve(source);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_invalidOverrideDifferentDefaultValues_positional() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  m([int p = 0]) {}", "}", "class B extends A {", "  m([int p = 0]) {}", "}"]));
+    resolve(source);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_invalidOverrideDifferentDefaultValues_positional_changedOrder() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  m([int a = 0, String b = '0']) {}", "}", "class B extends A {", "  m([int b = 0, String a = '0']) {}", "}"]));
+    resolve(source);
+    assertNoErrors();
+    verify([source]);
+  }
   void test_invalidOverrideNamed_unorderedNamedParameter() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  m({a, b}) {}", "}", "class B extends A {", "  m({b, a}) {}", "}"]));
     resolve(source);
@@ -1157,6 +1181,42 @@
     assertNoErrors();
     verify([source]);
   }
+  void test_nonConstantDefaultValue_function_named() {
+    Source source = addSource(EngineTestCase.createSource(["f({x : 2 + 3}) {}"]));
+    resolve(source);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_nonConstantDefaultValue_function_positional() {
+    Source source = addSource(EngineTestCase.createSource(["f([x = 2 + 3]) {}"]));
+    resolve(source);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_nonConstantDefaultValue_inConstructor_named() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  A({x : 2 + 3}) {}", "}"]));
+    resolve(source);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_nonConstantDefaultValue_inConstructor_positional() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  A([x = 2 + 3]) {}", "}"]));
+    resolve(source);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_nonConstantDefaultValue_method_named() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  m({x : 2 + 3}) {}", "}"]));
+    resolve(source);
+    assertNoErrors();
+    verify([source]);
+  }
+  void test_nonConstantDefaultValue_method_positional() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  m([x = 2 + 3]) {}", "}"]));
+    resolve(source);
+    assertNoErrors();
+    verify([source]);
+  }
   void test_nonConstCaseExpression() {
     Source source = addSource(EngineTestCase.createSource(["f(Type t) {", "  switch (t) {", "    case bool:", "    case int:", "      return true;", "    default:", "      return false;", "  }", "}"]));
     resolve(source);
@@ -1445,6 +1505,12 @@
     assertNoErrors();
     verify([source]);
   }
+  void test_undefinedConstructorInInitializer_hasOptionalParameters() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  A([p]) {}", "}", "class B extends A {", "  B();", "}"]));
+    resolve(source);
+    assertNoErrors();
+    verify([source]);
+  }
   void test_undefinedConstructorInInitializer_implicit() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  A() {}", "}", "class B extends A {", "  B();", "}"]));
     resolve(source);
@@ -1869,6 +1935,22 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_invalidFactoryNameNotAClass);
       });
+      _ut.test('test_invalidMethodOverrideNamedParamType', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_invalidMethodOverrideNamedParamType);
+      });
+      _ut.test('test_invalidOverrideDifferentDefaultValues_named', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_invalidOverrideDifferentDefaultValues_named);
+      });
+      _ut.test('test_invalidOverrideDifferentDefaultValues_positional', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_invalidOverrideDifferentDefaultValues_positional);
+      });
+      _ut.test('test_invalidOverrideDifferentDefaultValues_positional_changedOrder', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_invalidOverrideDifferentDefaultValues_positional_changedOrder);
+      });
       _ut.test('test_invalidOverrideNamed_unorderedNamedParameter', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_invalidOverrideNamed_unorderedNamedParameter);
@@ -2053,6 +2135,30 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_nonConstValueInInitializer_unary);
       });
+      _ut.test('test_nonConstantDefaultValue_function_named', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_nonConstantDefaultValue_function_named);
+      });
+      _ut.test('test_nonConstantDefaultValue_function_positional', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_nonConstantDefaultValue_function_positional);
+      });
+      _ut.test('test_nonConstantDefaultValue_inConstructor_named', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_nonConstantDefaultValue_inConstructor_named);
+      });
+      _ut.test('test_nonConstantDefaultValue_inConstructor_positional', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_nonConstantDefaultValue_inConstructor_positional);
+      });
+      _ut.test('test_nonConstantDefaultValue_method_named', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_nonConstantDefaultValue_method_named);
+      });
+      _ut.test('test_nonConstantDefaultValue_method_positional', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_nonConstantDefaultValue_method_positional);
+      });
       _ut.test('test_nonGenerativeConstructor', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_nonGenerativeConstructor);
@@ -2197,6 +2303,10 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_undefinedConstructorInInitializer_explicit_unnamed);
       });
+      _ut.test('test_undefinedConstructorInInitializer_hasOptionalParameters', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_undefinedConstructorInInitializer_hasOptionalParameters);
+      });
       _ut.test('test_undefinedConstructorInInitializer_implicit', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_undefinedConstructorInInitializer_implicit);
@@ -2548,12 +2658,48 @@
     assertErrors([StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
     verify([source]);
   }
+  void test_returnOfInvalidType_expressionFunctionBody_function() {
+    Source source = addSource(EngineTestCase.createSource(["int f() => '0';"]));
+    resolve(source);
+    assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+    verify([source]);
+  }
+  void test_returnOfInvalidType_expressionFunctionBody_getter() {
+    Source source = addSource(EngineTestCase.createSource(["int get g => '0';"]));
+    resolve(source);
+    assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+    verify([source]);
+  }
+  void test_returnOfInvalidType_expressionFunctionBody_localFunction() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  String m() {", "    int f() => '0';", "  }", "}"]));
+    resolve(source);
+    assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+    verify([source]);
+  }
+  void test_returnOfInvalidType_expressionFunctionBody_method() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  int f() => '0';", "}"]));
+    resolve(source);
+    assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+    verify([source]);
+  }
+  void test_returnOfInvalidType_expressionFunctionBody_void() {
+    Source source = addSource(EngineTestCase.createSource(["void f() => 42;"]));
+    resolve(source);
+    assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+    verify([source]);
+  }
   void test_returnOfInvalidType_function() {
     Source source = addSource(EngineTestCase.createSource(["int f() { return '0'; }"]));
     resolve(source);
     assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
     verify([source]);
   }
+  void test_returnOfInvalidType_getter() {
+    Source source = addSource(EngineTestCase.createSource(["int get g { return '0'; }"]));
+    resolve(source);
+    assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+    verify([source]);
+  }
   void test_returnOfInvalidType_localFunction() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  String m() {", "    int f() { return '0'; }", "  }", "}"]));
     resolve(source);
@@ -2604,6 +2750,11 @@
     resolve(source);
     assertErrors([StaticTypeWarningCode.UNDEFINED_METHOD]);
   }
+  void test_undefinedMethod_ignoreTypePropagation() {
+    Source source = addSource(EngineTestCase.createSource(["class A {}", "class B extends A {", "  m() {}", "}", "class C {", "f() {", "    A a = new B();", "    a.m();", "  }", "}"]));
+    resolve(source);
+    assertErrors([StaticTypeWarningCode.UNDEFINED_METHOD]);
+  }
   void test_undefinedOperator_indexBoth() {
     Source source = addSource(EngineTestCase.createSource(["class A {}", "f(A a) {", "  a[0]++;", "}"]));
     resolve(source);
@@ -2725,10 +2876,34 @@
         final __test = new StaticTypeWarningCodeTest();
         runJUnitTest(__test, __test.test_nonBoolExpression);
       });
+      _ut.test('test_returnOfInvalidType_expressionFunctionBody_function', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_returnOfInvalidType_expressionFunctionBody_function);
+      });
+      _ut.test('test_returnOfInvalidType_expressionFunctionBody_getter', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_returnOfInvalidType_expressionFunctionBody_getter);
+      });
+      _ut.test('test_returnOfInvalidType_expressionFunctionBody_localFunction', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_returnOfInvalidType_expressionFunctionBody_localFunction);
+      });
+      _ut.test('test_returnOfInvalidType_expressionFunctionBody_method', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_returnOfInvalidType_expressionFunctionBody_method);
+      });
+      _ut.test('test_returnOfInvalidType_expressionFunctionBody_void', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_returnOfInvalidType_expressionFunctionBody_void);
+      });
       _ut.test('test_returnOfInvalidType_function', () {
         final __test = new StaticTypeWarningCodeTest();
         runJUnitTest(__test, __test.test_returnOfInvalidType_function);
       });
+      _ut.test('test_returnOfInvalidType_getter', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_returnOfInvalidType_getter);
+      });
       _ut.test('test_returnOfInvalidType_localFunction', () {
         final __test = new StaticTypeWarningCodeTest();
         runJUnitTest(__test, __test.test_returnOfInvalidType_localFunction);
@@ -2765,6 +2940,10 @@
         final __test = new StaticTypeWarningCodeTest();
         runJUnitTest(__test, __test.test_undefinedMethod);
       });
+      _ut.test('test_undefinedMethod_ignoreTypePropagation', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_undefinedMethod_ignoreTypePropagation);
+      });
       _ut.test('test_undefinedOperator_indexBoth', () {
         final __test = new StaticTypeWarningCodeTest();
         runJUnitTest(__test, __test.test_undefinedOperator_indexBoth);
@@ -3115,7 +3294,7 @@
 class ResolverTestCase extends EngineTestCase {
 
   /**
-   * The source factory used to create {@link Source sources}.
+   * The source factory used to create [Source sources].
    */
   SourceFactory _sourceFactory;
 
@@ -3194,7 +3373,7 @@
   }
 
   /**
-   * Create a library element that represents a library named {@code "test"} containing a single
+   * Create a library element that represents a library named `"test"` containing a single
    * empty compilation unit.
    * @return the library element that was created
    */
@@ -3251,7 +3430,7 @@
   /**
    * Given a library and all of its parts, resolve the contents of the library and the contents of
    * the parts. This assumes that the sources for the library and its parts have already been added
-   * to the content provider using the method {@link #addSource(String,String)}.
+   * to the content provider using the method [addSource].
    * @param librarySource the source for the compilation unit that defines the library
    * @return the element representing the resolved library
    * @throws AnalysisException if the analysis could not be performed
@@ -3880,18 +4059,6 @@
     assertErrors([CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
     verify([source]);
   }
-  void fail_nonConstantDefaultValue_named() {
-    Source source = addSource(EngineTestCase.createSource(["f({x : 2 + 3}) {}"]));
-    resolve(source);
-    assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
-    verify([source]);
-  }
-  void fail_nonConstantDefaultValue_positional() {
-    Source source = addSource(EngineTestCase.createSource(["f([x = 2 + 3]) {}"]));
-    resolve(source);
-    assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
-    verify([source]);
-  }
   void fail_objectCannotExtendAnotherClass() {
     Source source = addSource(EngineTestCase.createSource([]));
     resolve(source);
@@ -3940,24 +4107,6 @@
     assertErrors([CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT]);
     verify([source]);
   }
-  void fail_typeArgumentsForNonGenericClass_creation_const() {
-    Source source = addSource(EngineTestCase.createSource(["class A {}", "f(p) {", "  return const A<int>();", "}"]));
-    resolve(source);
-    assertErrors([CompileTimeErrorCode.TYPE_ARGUMENTS_FOR_NON_GENERIC_CLASS]);
-    verify([source]);
-  }
-  void fail_typeArgumentsForNonGenericClass_creation_new() {
-    Source source = addSource(EngineTestCase.createSource(["class A {}", "f(p) {", "  return new A<int>();", "}"]));
-    resolve(source);
-    assertErrors([CompileTimeErrorCode.TYPE_ARGUMENTS_FOR_NON_GENERIC_CLASS]);
-    verify([source]);
-  }
-  void fail_typeArgumentsForNonGenericClass_typeCast() {
-    Source source = addSource(EngineTestCase.createSource(["class A {}", "f(p) {", "  return p as A<int>;", "}"]));
-    resolve(source);
-    assertErrors([CompileTimeErrorCode.TYPE_ARGUMENTS_FOR_NON_GENERIC_CLASS]);
-    verify([source]);
-  }
   void fail_uninitializedFinalField() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  final int i;", "}"]));
     resolve(source);
@@ -4364,31 +4513,31 @@
   void test_extendsOrImplementsDisallowedClass_extends_bool() {
     Source source = addSource(EngineTestCase.createSource(["class A extends bool {}"]));
     resolve(source);
-    assertErrors([CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    assertErrors([CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS, StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
     verify([source]);
   }
   void test_extendsOrImplementsDisallowedClass_extends_double() {
     Source source = addSource(EngineTestCase.createSource(["class A extends double {}"]));
     resolve(source);
-    assertErrors([CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    assertErrors([CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS, StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
     verify([source]);
   }
   void test_extendsOrImplementsDisallowedClass_extends_int() {
     Source source = addSource(EngineTestCase.createSource(["class A extends int {}"]));
     resolve(source);
-    assertErrors([CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    assertErrors([CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS, StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
     verify([source]);
   }
   void test_extendsOrImplementsDisallowedClass_extends_num() {
     Source source = addSource(EngineTestCase.createSource(["class A extends num {}"]));
     resolve(source);
-    assertErrors([CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    assertErrors([CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS, StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
     verify([source]);
   }
   void test_extendsOrImplementsDisallowedClass_extends_String() {
     Source source = addSource(EngineTestCase.createSource(["class A extends String {}"]));
     resolve(source);
-    assertErrors([CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    assertErrors([CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS, StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
     verify([source]);
   }
   void test_extendsOrImplementsDisallowedClass_implements_bool() {
@@ -4504,7 +4653,7 @@
    * This test doesn't test the FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR code, but tests the
    * FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION code instead. It is provided here to show
    * coverage over all of the permutations of initializers in constructor declarations.
-   * <p>
+   *
    * Note: FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION covers a subset of
    * FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR, since it more specific, we use it instead of
    * the broader code
@@ -4532,7 +4681,7 @@
    * This test doesn't test the FINAL_INITIALIZED_MULTIPLE_TIMES code, but tests the
    * FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER code instead. It is provided here to show
    * coverage over all of the permutations of initializers in constructor declarations.
-   * <p>
+   *
    * Note: FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER covers a subset of
    * FINAL_INITIALIZED_MULTIPLE_TIMES, since it more specific, we use it instead of the broader code
    */
@@ -4926,6 +5075,42 @@
     assertErrors([CompileTimeErrorCode.NEW_WITH_INVALID_TYPE_PARAMETERS]);
     verify([source]);
   }
+  void test_nonConstantDefaultValue_function_named() {
+    Source source = addSource(EngineTestCase.createSource(["int y;", "f({x : y}) {}"]));
+    resolve(source);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+  void test_nonConstantDefaultValue_function_positional() {
+    Source source = addSource(EngineTestCase.createSource(["int y;", "f([x = y]) {}"]));
+    resolve(source);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+  void test_nonConstantDefaultValue_inConstructor_named() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  int y;", "  A({x : y}) {}", "}"]));
+    resolve(source);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+  void test_nonConstantDefaultValue_inConstructor_positional() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  int y;", "  A([x = y]) {}", "}"]));
+    resolve(source);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+  void test_nonConstantDefaultValue_method_named() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  int y;", "  m({x : y}) {}", "}"]));
+    resolve(source);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+  void test_nonConstantDefaultValue_method_positional() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  int y;", "  m([x = y]) {}", "}"]));
+    resolve(source);
+    assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
   void test_nonConstCaseExpression() {
     Source source = addSource(EngineTestCase.createSource(["f(int p, int q) {", "  switch (p) {", "    case 3 + q:", "      break;", "  }", "}"]));
     resolve(source);
@@ -6076,6 +6261,30 @@
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_nonConstValueInInitializer_super);
       });
+      _ut.test('test_nonConstantDefaultValue_function_named', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_nonConstantDefaultValue_function_named);
+      });
+      _ut.test('test_nonConstantDefaultValue_function_positional', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_nonConstantDefaultValue_function_positional);
+      });
+      _ut.test('test_nonConstantDefaultValue_inConstructor_named', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_nonConstantDefaultValue_inConstructor_named);
+      });
+      _ut.test('test_nonConstantDefaultValue_inConstructor_positional', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_nonConstantDefaultValue_inConstructor_positional);
+      });
+      _ut.test('test_nonConstantDefaultValue_method_named', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_nonConstantDefaultValue_method_named);
+      });
+      _ut.test('test_nonConstantDefaultValue_method_positional', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_nonConstantDefaultValue_method_positional);
+      });
       _ut.test('test_nonGenerativeConstructor_explicit', () {
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_nonGenerativeConstructor_explicit);
@@ -6324,7 +6533,7 @@
   }
 }
 /**
- * Instances of the class {@code StaticTypeVerifier} verify that all of the nodes in an AST
+ * Instances of the class `StaticTypeVerifier` verify that all of the nodes in an AST
  * structure that should have a static type associated with them do have a static type.
  */
 class StaticTypeVerifier extends GeneralizingASTVisitor<Object> {
@@ -6458,7 +6667,7 @@
   }
 }
 /**
- * The class {@code StrictModeTest} contains tests to ensure that the correct errors and warnings
+ * The class `StrictModeTest` contains tests to ensure that the correct errors and warnings
  * are reported when the analysis engine is run in strict mode.
  */
 class StrictModeTest extends ResolverTestCase {
@@ -6960,7 +7169,7 @@
     resolveInClass(node, classA);
     Element element = node.element;
     EngineTestCase.assertInstanceOf(PropertyAccessorElement, element);
-    JUnitTestCase.assertTrue(((element as PropertyAccessorElement)).isSetter());
+    JUnitTestCase.assertTrue(((element as PropertyAccessorElement)).isSetter);
     _listener.assertNoErrors();
   }
   void test_visitSuperConstructorInvocation() {
@@ -7538,12 +7747,6 @@
     assertErrors([StaticWarningCode.INVALID_FACTORY_NAME]);
     verify([source]);
   }
-  void fail_invalidOverrideDifferentDefaultValues() {
-    Source source = addSource(EngineTestCase.createSource(["class A {", "  m([int p = 0]) {}", "}", "class B extends A {", "  m([int p = 1]) {}", "}"]));
-    resolve(source);
-    assertErrors([StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES]);
-    verify([source]);
-  }
   void fail_invocationOfNonFunction() {
     Source source = addSource(EngineTestCase.createSource([]));
     resolve(source);
@@ -8041,6 +8244,18 @@
     assertErrors([StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
     verify([source]);
   }
+  void test_invalidOverrideDifferentDefaultValues_named() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  m({int p : 0}) {}", "}", "class B extends A {", "  m({int p : 1}) {}", "}"]));
+    resolve(source);
+    assertErrors([StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED]);
+    verify([source]);
+  }
+  void test_invalidOverrideDifferentDefaultValues_positional() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  m([int p = 0]) {}", "}", "class B extends A {", "  m([int p = 1]) {}", "}"]));
+    resolve(source);
+    assertErrors([StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL]);
+    verify([source]);
+  }
   void test_invalidSetterOverrideNormalParamType() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  void set s(int v) {}", "}", "class B extends A {", "  void set s(String v) {}", "}"]));
     resolve(source);
@@ -8082,6 +8297,24 @@
     assertErrors([StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]);
     verify([source]);
   }
+  void test_noDefaultSuperConstructorExplicit() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  A(p);", "}", "class B extends A {", "  B() {}", "}"]));
+    resolve(source);
+    assertErrors([StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]);
+    verify([source]);
+  }
+  void test_noDefaultSuperConstructorImplicit_superHasParameters() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  A(p);", "}", "class B extends A {", "}"]));
+    resolve(source);
+    assertErrors([StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
+    verify([source]);
+  }
+  void test_noDefaultSuperConstructorImplicit_superOnlyNamed() {
+    Source source = addSource(EngineTestCase.createSource(["class A { A.named() {} }", "class B extends A {}"]));
+    resolve(source);
+    assertErrors([StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
+    verify([source]);
+  }
   void test_nonAbstractClassInheritsAbstractMemberFivePlus() {
     Source source = addSource(EngineTestCase.createSource(["abstract class A {", "  m();", "  n();", "  o();", "  p();", "  q();", "}", "class C extends A {", "}"]));
     resolve(source);
@@ -8136,6 +8369,12 @@
     assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
+  void test_nonAbstractClassInheritsAbstractMemberOne_superclasses_interface() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  get a => 'a';", "}", "abstract class B implements A {", "  get b => 'b';", "}", "class C extends B {", "}"]));
+    resolve(source);
+    assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+    verify([source]);
+  }
   void test_nonAbstractClassInheritsAbstractMemberThree() {
     Source source = addSource(EngineTestCase.createSource(["abstract class A {", "  m();", "  n();", "  o();", "}", "class C extends A {", "}"]));
     resolve(source);
@@ -8602,6 +8841,14 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_invalidMethodOverrideReturnType_void);
       });
+      _ut.test('test_invalidOverrideDifferentDefaultValues_named', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_invalidOverrideDifferentDefaultValues_named);
+      });
+      _ut.test('test_invalidOverrideDifferentDefaultValues_positional', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_invalidOverrideDifferentDefaultValues_positional);
+      });
       _ut.test('test_invalidSetterOverrideNormalParamType', () {
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_invalidSetterOverrideNormalParamType);
@@ -8630,6 +8877,18 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_newWithUndefinedConstructorDefault);
       });
+      _ut.test('test_noDefaultSuperConstructorExplicit', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_noDefaultSuperConstructorExplicit);
+      });
+      _ut.test('test_noDefaultSuperConstructorImplicit_superHasParameters', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_noDefaultSuperConstructorImplicit_superHasParameters);
+      });
+      _ut.test('test_noDefaultSuperConstructorImplicit_superOnlyNamed', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_noDefaultSuperConstructorImplicit_superOnlyNamed);
+      });
       _ut.test('test_nonAbstractClassInheritsAbstractMemberFivePlus', () {
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberFivePlus);
@@ -8666,6 +8925,10 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_setter_fromSuperclass);
       });
+      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_superclasses_interface', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_superclasses_interface);
+      });
       _ut.test('test_nonAbstractClassInheritsAbstractMemberThree', () {
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberThree);
@@ -8816,7 +9079,7 @@
   }
 }
 /**
- * Instances of the class {@code TestTypeProvider} implement a type provider that can be used by
+ * Instances of the class `TestTypeProvider` implement a type provider that can be used by
  * tests without creating the element model for the core library.
  */
 class TestTypeProvider implements TypeProvider {
@@ -8937,6 +9200,7 @@
       _iterableType = iterableElement.type;
       Type2 eType = iterableElement.typeVariables[0].type;
       iterableElement.accessors = <PropertyAccessorElement> [ElementFactory.getterElement("iterator", false, iteratorType.substitute5(<Type2> [eType])), ElementFactory.getterElement("last", false, eType)];
+      propagateTypeArguments(iterableElement);
     }
     return _iterableType;
   }
@@ -8946,6 +9210,7 @@
       _iteratorType = iteratorElement.type;
       Type2 eType = iteratorElement.typeVariables[0].type;
       iteratorElement.accessors = <PropertyAccessorElement> [ElementFactory.getterElement("current", false, eType)];
+      propagateTypeArguments(iteratorElement);
     }
     return _iteratorType;
   }
@@ -8958,7 +9223,8 @@
       InterfaceType supertype = iterableType.substitute5(<Type2> [eType]);
       listElement.supertype = supertype;
       listElement.accessors = <PropertyAccessorElement> [ElementFactory.getterElement("length", false, intType)];
-      listElement.methods = <MethodElement> [ElementFactory.methodElement("[]", eType, [intType]), ElementFactory.methodElement("[]=", VoidTypeImpl.instance, [intType, eType])];
+      listElement.methods = <MethodElement> [ElementFactory.methodElement("[]", eType, [intType]), ElementFactory.methodElement("[]=", VoidTypeImpl.instance, [intType, eType]), ElementFactory.methodElement("add", VoidTypeImpl.instance, [eType])];
+      propagateTypeArguments(listElement);
     }
     return _listType;
   }
@@ -8967,6 +9233,7 @@
       ClassElementImpl mapElement = ElementFactory.classElement2("Map", ["K", "V"]);
       _mapType = mapElement.type;
       mapElement.accessors = <PropertyAccessorElement> [ElementFactory.getterElement("length", false, intType)];
+      propagateTypeArguments(mapElement);
     }
     return _mapType;
   }
@@ -9035,9 +9302,30 @@
     doubleElement.accessors = accessors;
     doubleElement.methods = <MethodElement> [ElementFactory.methodElement("remainder", _doubleType, [_numType]), ElementFactory.methodElement("+", _doubleType, [_numType]), ElementFactory.methodElement("-", _doubleType, [_numType]), ElementFactory.methodElement("*", _doubleType, [_numType]), ElementFactory.methodElement("%", _doubleType, [_numType]), ElementFactory.methodElement("/", _doubleType, [_numType]), ElementFactory.methodElement("~/", _doubleType, [_numType]), ElementFactory.methodElement("-", _doubleType, []), ElementFactory.methodElement("abs", _doubleType, []), ElementFactory.methodElement("round", _doubleType, []), ElementFactory.methodElement("floor", _doubleType, []), ElementFactory.methodElement("ceil", _doubleType, []), ElementFactory.methodElement("truncate", _doubleType, []), ElementFactory.methodElement("toString", _stringType, [])];
   }
+
+  /**
+   * Given a class element representing a class with type parameters, propagate those type
+   * parameters to all of the accessors, methods and constructors defined for the class.
+   * @param classElement the element representing the class with type parameters
+   */
+  void propagateTypeArguments(ClassElementImpl classElement) {
+    List<Type2> typeArguments = TypeVariableTypeImpl.getTypes(classElement.typeVariables);
+    for (PropertyAccessorElement accessor in classElement.accessors) {
+      FunctionTypeImpl functionType = accessor.type as FunctionTypeImpl;
+      functionType.typeArguments = typeArguments;
+    }
+    for (MethodElement method in classElement.methods) {
+      FunctionTypeImpl functionType = method.type as FunctionTypeImpl;
+      functionType.typeArguments = typeArguments;
+    }
+    for (ConstructorElement constructor in classElement.constructors) {
+      FunctionTypeImpl functionType = constructor.type as FunctionTypeImpl;
+      functionType.typeArguments = typeArguments;
+    }
+  }
 }
 /**
- * The class {@code AnalysisContextFactory} defines utility methods used to create analysis contexts
+ * The class `AnalysisContextFactory` defines utility methods used to create analysis contexts
  * for testing purposes.
  */
 class AnalysisContextFactory {
@@ -9210,7 +9498,7 @@
   }
 }
 /**
- * Instances of the class {@code ResolutionVerifier} verify that all of the nodes in an AST
+ * Instances of the class `ResolutionVerifier` verify that all of the nodes in an AST
  * structure that should have been resolved were resolved.
  */
 class ResolutionVerifier extends RecursiveASTVisitor<Object> {
@@ -9280,7 +9568,7 @@
   }
   Object visitBinaryExpression(BinaryExpression node) {
     node.visitChildren(this);
-    if (!node.operator.isUserDefinableOperator()) {
+    if (!node.operator.isUserDefinableOperator) {
       return null;
     }
     return checkResolved2(node, node.element, MethodElement);
@@ -9318,14 +9606,14 @@
   Object visitPartOfDirective(PartOfDirective node) => checkResolved2(node, node.element, LibraryElement);
   Object visitPostfixExpression(PostfixExpression node) {
     node.visitChildren(this);
-    if (!node.operator.isUserDefinableOperator()) {
+    if (!node.operator.isUserDefinableOperator) {
       return null;
     }
     return checkResolved2(node, node.element, MethodElement);
   }
   Object visitPrefixExpression(PrefixExpression node) {
     node.visitChildren(this);
-    if (!node.operator.isUserDefinableOperator()) {
+    if (!node.operator.isUserDefinableOperator) {
       return null;
     }
     return checkResolved2(node, node.element, MethodElement);
@@ -9771,8 +10059,8 @@
     ClassElementImpl classElement = ElementFactory.classElement2("C", []);
     String constructorName = "m";
     ConstructorElementImpl constructor = ElementFactory.constructorElement(classElement, constructorName);
+    constructor.returnType = classElement.type;
     FunctionTypeImpl constructorType = new FunctionTypeImpl.con1(constructor);
-    constructorType.returnType = classElement.type;
     constructor.type = constructorType;
     classElement.constructors = <ConstructorElement> [constructor];
     InstanceCreationExpression node = ASTFactory.instanceCreationExpression2(null, ASTFactory.typeName(classElement, []), [ASTFactory.identifier3(constructorName)]);
@@ -9785,8 +10073,8 @@
     ClassElementImpl elementI = ElementFactory.classElement2("I", []);
     ConstructorElementImpl constructor = ElementFactory.constructorElement(elementC, null);
     elementC.constructors = <ConstructorElement> [constructor];
+    constructor.returnType = elementC.type;
     FunctionTypeImpl constructorType = new FunctionTypeImpl.con1(constructor);
-    constructorType.returnType = elementC.type;
     constructor.type = constructorType;
     TypeName typeName = ASTFactory.typeName(elementC, [ASTFactory.typeName(elementI, [])]);
     typeName.type = elementC.type.substitute5(<Type2> [elementI.type]);
@@ -9801,8 +10089,8 @@
   void test_visitInstanceCreationExpression_unnamed() {
     ClassElementImpl classElement = ElementFactory.classElement2("C", []);
     ConstructorElementImpl constructor = ElementFactory.constructorElement(classElement, null);
+    constructor.returnType = classElement.type;
     FunctionTypeImpl constructorType = new FunctionTypeImpl.con1(constructor);
-    constructorType.returnType = classElement.type;
     constructor.type = constructorType;
     classElement.constructors = <ConstructorElement> [constructor];
     InstanceCreationExpression node = ASTFactory.instanceCreationExpression2(null, ASTFactory.typeName(classElement, []), []);
@@ -10125,7 +10413,7 @@
 
   /**
    * Create a function expression that has an element associated with it, where the element has an
-   * incomplete type associated with it (just like the one{@link ElementBuilder#visitFunctionExpression(FunctionExpression)} would have built if we had
+   * incomplete type associated with it (just like the one[ElementBuilder#visitFunctionExpression] would have built if we had
    * run it).
    * @param parameters the parameters to the function
    * @param body the body of the function
@@ -10529,7 +10817,7 @@
 class LibraryElementBuilderTest extends EngineTestCase {
 
   /**
-   * The source factory used to create {@link Source sources}.
+   * The source factory used to create [Source sources].
    */
   SourceFactory _sourceFactory;
   void setUp() {
@@ -10964,7 +11252,7 @@
     JUnitTestCase.assertNotNull(unit);
     List<ClassElement> classes = unit.types;
     EngineTestCase.assertLength(2, classes);
-    JUnitTestCase.assertFalse(classes[0].isValidMixin());
+    JUnitTestCase.assertFalse(classes[0].isValidMixin);
     assertNoErrors();
     verify([source]);
   }
@@ -10976,7 +11264,7 @@
     JUnitTestCase.assertNotNull(unit);
     List<ClassElement> classes = unit.types;
     EngineTestCase.assertLength(1, classes);
-    JUnitTestCase.assertFalse(classes[0].isValidMixin());
+    JUnitTestCase.assertFalse(classes[0].isValidMixin);
     assertNoErrors();
     verify([source]);
   }
@@ -10988,7 +11276,7 @@
     JUnitTestCase.assertNotNull(unit);
     List<ClassElement> classes = unit.types;
     EngineTestCase.assertLength(1, classes);
-    JUnitTestCase.assertFalse(classes[0].isValidMixin());
+    JUnitTestCase.assertFalse(classes[0].isValidMixin);
     assertNoErrors();
     verify([source]);
   }
@@ -11000,7 +11288,7 @@
     JUnitTestCase.assertNotNull(unit);
     List<ClassElement> classes = unit.types;
     EngineTestCase.assertLength(1, classes);
-    JUnitTestCase.assertTrue(classes[0].isValidMixin());
+    JUnitTestCase.assertTrue(classes[0].isValidMixin);
     assertNoErrors();
     verify([source]);
   }
@@ -11092,7 +11380,7 @@
     verify([source]);
   }
   void test_setter_inherited() {
-    Source source = addSource(EngineTestCase.createSource(["class A {", "  int get x => 0;", "  set x(int p) {}", "}", "class B extends A {", "  int get x => super.x == null ? 0 : super.x;", "  void f() => x = 1;", "}"]));
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  int get x => 0;", "  set x(int p) {}", "}", "class B extends A {", "  int get x => super.x == null ? 0 : super.x;", "  int f() => x = 1;", "}"]));
     resolve(source);
     assertNoErrors();
     verify([source]);
@@ -11107,13 +11395,13 @@
   /**
    * Resolve the given source and verify that the arguments in a specific method invocation were
    * correctly resolved.
-   * <p>
+   *
    * The source is expected to be source for a compilation unit, the first declaration is expected
    * to be a class, the first member of which is expected to be a method with a block body, and the
    * first statement in the body is expected to be an expression statement whose expression is a
    * method invocation. It is the arguments to that method invocation that are tested. The method
    * invocation can contain errors.
-   * <p>
+   *
    * The arguments were resolved correctly if the number of expressions in the list matches the
    * length of the array of indices and if, for each index in the array of indices, the parameter to
    * which the argument expression was resolved is the parameter in the invoked method's list of
@@ -11347,7 +11635,6 @@
 //  CompileTimeErrorCodeTest.dartSuite();
 //  ErrorResolverTest.dartSuite();
 //  NonErrorResolverTest.dartSuite();
-//  PubSuggestionCodeTest.dartSuite();
 //  SimpleResolverTest.dartSuite();
 //  StaticTypeWarningCodeTest.dartSuite();
 //  StaticWarningCodeTest.dartSuite();
diff --git a/pkg/analyzer_experimental/test/generated/scanner_test.dart b/pkg/analyzer_experimental/test/generated/scanner_test.dart
index e9ff970..b48df5f 100644
--- a/pkg/analyzer_experimental/test/generated/scanner_test.dart
+++ b/pkg/analyzer_experimental/test/generated/scanner_test.dart
@@ -53,67 +53,67 @@
 }
 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());
+    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());
+    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', () {
@@ -129,7 +129,7 @@
   }
 }
 /**
- * The class {@code TokenFactory} defines utility methods that can be used to create tokens.
+ * The class `TokenFactory` defines utility methods that can be used to create tokens.
  */
 class TokenFactory {
   static Token token(Keyword keyword) => new KeywordToken(keyword, 0);
@@ -1474,7 +1474,7 @@
   }
 }
 /**
- * Instances of the class {@code TokenStreamValidator} are used to validate the correct construction
+ * Instances of the class `TokenStreamValidator` are used to validate the correct construction
  * of a stream of tokens.
  */
 class TokenStreamValidator {
@@ -2156,7 +2156,7 @@
   }
 }
 /**
- * Instances of the class {@code ExpectedLocation} encode information about the expected location
+ * Instances of the class `ExpectedLocation` encode information about the expected location
  * of a given offset in source code.
  */
 class AbstractScannerTest_ExpectedLocation {
diff --git a/pkg/analyzer_experimental/test/generated/test_support.dart b/pkg/analyzer_experimental/test/generated/test_support.dart
index ea44668..6b39ac8 100644
--- a/pkg/analyzer_experimental/test/generated/test_support.dart
+++ b/pkg/analyzer_experimental/test/generated/test_support.dart
@@ -12,7 +12,7 @@
 import 'package:analyzer_experimental/src/generated/engine.dart' show AnalysisContext, AnalysisContextImpl, RecordingErrorListener;
 import 'package:unittest/unittest.dart' as _ut;
 /**
- * Instances of the class {@code GatheringErrorListener} implement an error listener that collects
+ * Instances of the class `GatheringErrorListener` implement an error listener that collects
  * all of the errors passed to it for later examination.
  */
 class GatheringErrorListener implements AnalysisErrorListener {
@@ -227,7 +227,7 @@
   List<AnalysisError> get errors => _errors;
 
   /**
-   * Return the line information associated with the given source, or {@code null} if no line
+   * Return the line information associated with the given source, or `null` if no line
    * information has been associated with the source.
    * @param source the source with which the line information is associated
    * @return the line information associated with the source
@@ -235,9 +235,9 @@
   LineInfo getLineInfo(Source source) => _lineInfoMap[source];
 
   /**
-   * Return {@code true} if an error with the given error code has been gathered.
+   * Return `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
+   * @return `true` if an error with the given error code has been gathered
    */
   bool hasError(ErrorCode errorCode2) {
     for (AnalysisError error in _errors) {
@@ -249,8 +249,8 @@
   }
 
   /**
-   * Return {@code true} if at least one error has been gathered.
-   * @return {@code true} if at least one error has been gathered
+   * Return `true` if at least one error has been gathered.
+   * @return `true` if at least one error has been gathered
    */
   bool hasErrors() => _errors.length > 0;
   void onError(AnalysisError error) {
@@ -281,18 +281,18 @@
   }
 
   /**
-   * Return {@code true} if the two errors are equivalent.
+   * Return `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
+   * @return `true` if the two errors are equivalent
    */
   bool equals3(AnalysisError firstError, AnalysisError secondError) => identical(firstError.errorCode, secondError.errorCode) && firstError.offset == secondError.offset && firstError.length == secondError.length && equals4(firstError.source, secondError.source);
 
   /**
-   * Return {@code true} if the two sources are equivalent.
+   * Return `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
+   * @return `true` if the two sources are equivalent
    */
   bool equals4(Source firstSource, Source secondSource) {
     if (firstSource == null) {
@@ -348,10 +348,10 @@
 
   /**
    * 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.
+   * is found, remove it from the list and return `true`, otherwise return `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
+   * @return `true` if the error is found and removed from the list
    */
   bool foundAndRemoved(List<AnalysisError> errors, AnalysisError targetError) {
     for (AnalysisError error in errors) {
@@ -364,7 +364,7 @@
   }
 }
 /**
- * The class {@code EngineTestCase} defines utility methods for making assertions.
+ * The class `EngineTestCase` defines utility methods for making assertions.
  */
 class EngineTestCase extends JUnitTestCase {
   static int _PRINT_RANGE = 6;
@@ -388,11 +388,11 @@
   }
 
   /**
-   * Assert that the given array is non-{@code null} and contains the expected elements. The
+   * Assert that the given array is non-`null` and contains the expected elements. The
    * elements can appear in any order.
    * @param array the array being tested
    * @param expectedElements the expected elements
-   * @throws AssertionFailedError if the array is {@code null} or does not contain the expected
+   * @throws AssertionFailedError if the array is `null` or does not contain the expected
    * elements
    */
   static void assertContains(List<Object> array, List<Object> expectedElements) {
@@ -466,10 +466,10 @@
   }
 
   /**
-   * Assert that the given list is non-{@code null} and has exactly expected elements.
+   * Assert that the given list is non-`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
+   * @throws AssertionFailedError if the list is `null` or does not have the expected elements
    */
   static void assertExactElements(List<Object> list, List<Object> expectedElements) {
     int expectedSize = expectedElements.length;
@@ -489,10 +489,10 @@
   }
 
   /**
-   * Assert that the given array is non-{@code null} and has exactly expected elements.
+   * Assert that the given array is non-`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
+   * @throws AssertionFailedError if the array is `null` or does not have the expected
    * elements
    */
   static void assertExactElements2(List<Object> array, List<Object> expectedElements) {
@@ -513,10 +513,10 @@
   }
 
   /**
-   * Assert that the given list is non-{@code null} and has exactly expected elements.
+   * Assert that the given list is non-`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
+   * @throws AssertionFailedError if the list is `null` or does not have the expected elements
    */
   static void assertExactElements3(Set<Object> set, List<Object> expectedElements) {
     int expectedSize = expectedElements.length;
@@ -549,10 +549,10 @@
   }
 
   /**
-   * Assert that the given array is non-{@code null} and has the expected number of elements.
+   * Assert that the given array is non-`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
+   * @throws AssertionFailedError if the array is `null` or does not have the expected number
    * of elements
    */
   static void assertLength(int expectedLength, List<Object> array) {
@@ -582,10 +582,10 @@
   }
 
   /**
-   * Assert that the given list is non-{@code null} and has the expected number of elements.
+   * Assert that the given list is non-`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
+   * @throws AssertionFailedError if the list is `null` or does not have the expected number
    * of elements
    */
   static void assertSize(int expectedSize, List<Object> list) {
@@ -597,10 +597,10 @@
   }
 
   /**
-   * Assert that the given map is non-{@code null} and has the expected number of elements.
+   * Assert that the given map is non-`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
+   * @throws AssertionFailedError if the map is `null` or does not have the expected number of
    * elements
    */
   static void assertSize2(int expectedSize, Map<Object, Object> map) {
@@ -612,10 +612,10 @@
   }
 
   /**
-   * Assert that the given set is non-{@code null} and has the expected number of elements.
+   * Assert that the given set is non-`null` and has the expected number of elements.
    * @param expectedSize the expected number of elements
    * @param set the set being tested
-   * @throws AssertionFailedError if the set is {@code null} or does not have the expected number of
+   * @throws AssertionFailedError if the set is `null` or does not have the expected number of
    * elements
    */
   static void assertSize3(int expectedSize, Set<Object> set) {
@@ -696,7 +696,7 @@
    */
   PropertyAccessorElement getGetter(InterfaceType type, String getterName) {
     for (PropertyAccessorElement accessor in type.element.accessors) {
-      if (accessor.isGetter() && accessor.name == getterName) {
+      if (accessor.isGetter && accessor.name == getterName) {
         return accessor;
       }
     }
@@ -751,7 +751,7 @@
     throw new UnsupportedOperationException();
   }
   bool exists() => true;
-  bool isInSystemLibrary() {
+  bool get isInSystemLibrary {
     throw new UnsupportedOperationException();
   }
   Source resolve(String uri) {
diff --git a/pkg/analyzer_experimental/test/services/formatter_test.dart b/pkg/analyzer_experimental/test/services/formatter_test.dart
index d88d2d9..9bf1395 100644
--- a/pkg/analyzer_experimental/test/services/formatter_test.dart
+++ b/pkg/analyzer_experimental/test/services/formatter_test.dart
@@ -2,10 +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.
 
+import 'package:unittest/unittest.dart';
+
 import 'package:analyzer_experimental/src/generated/ast.dart';
+import 'package:analyzer_experimental/src/generated/scanner.dart';
 import 'package:analyzer_experimental/src/services/formatter.dart';
 import 'package:analyzer_experimental/src/services/formatter_impl.dart';
-import 'package:unittest/unittest.dart';
 
 main() {
 
@@ -18,35 +20,196 @@
       expect(newRecorder('  foo').countWhitespace(), equals(2));
     });
 
-    test('indent', (){
-      var recorder = newRecorder('');
-      expect(recorder.indentationLevel, equals(0));
-      expect(recorder.options.indentPerLevel, equals(2));
-      recorder.indent();
-      expect(recorder.indentationLevel, equals(2));
-      expect(recorder.numberOfIndentations, equals(1));
-    });
-
     test('isNewlineAt', (){
       expect(newRecorder('012\n').isNewlineAt(3), isTrue);
       expect(newRecorder('012\n3456').isNewlineAt(3), isTrue);
       expect(newRecorder('\n').isNewlineAt(0), isTrue);
     });
 
+    test('space advances 1', (){
+      var recorder = newRecorder(' foo');
+      var startColumn = recorder.column;
+      recorder.space();
+      expect(recorder.column, equals(startColumn + 1));
+    });
+
+    test('space eats WS (1)', (){
+      var recorder = newRecorder('  class')
+          ..currentToken = new KeywordToken(Keyword.CLASS, 3)
+          ..space()
+          ..advanceToken('class');
+      expect(doFormat(recorder), equals(' class'));
+    });
+
+    test('space eats WS (2)', (){
+      var src = 'class  A';
+      var recorder = newRecorder(src);
+      recorder..currentToken = (classKeyword(0)..setNext(identifier('A', 7)))
+              ..advanceToken('class')
+              ..space()
+              ..advanceToken('A');
+
+      expect(doFormat(recorder), equals('class A'));
+    });
+
+    test('advance string token', (){
+      var recorder = newRecorder('class A')..currentToken = classKeyword(0);
+      expect(recorder.column, equals(0));
+      recorder.advanceToken('class');
+      expect(recorder.column, equals(5));
+    });
+
+    test('advance string token (failure)', (){
+      var recorder = newRecorder('class A')..currentToken = classKeyword(0);
+      expect(() => recorder.advanceToken('static'),
+          throwsA(new isInstanceOf<FormatterException>()));
+    });
+
+    test('advance indent', (){
+      var recorder = newRecorder(' class A')..currentToken = classKeyword(0);
+      recorder.advanceIndent();
+      expect(doFormat(recorder), equals('class A'));
+    });
+
+    test('indent string', (){
+      var recorder = newRecorder('');
+      expect(recorder.getIndentString(0).length, equals(0));
+      expect(recorder.getIndentString(5).length, equals(5));
+      expect(recorder.getIndentString(50).length, equals(50));
+    });
+
+
+    test('newline', (){
+      var recorder = newRecorder('class A { }');
+      recorder..currentToken = chain([classKeyword(0),
+                                      identifier('A', 6),
+                                      openParen(8),
+                                      closeParen(10)])
+              ..advanceToken('class')
+              ..space()
+              ..advanceToken('A')
+              ..space()
+              ..advanceToken('{')
+              ..newline();
+
+      expect(doFormat(recorder)[9], equals(NEW_LINE));
+    });
+
+    test('newline eats trailing WS', (){
+      var src = 'class A {';
+      var recorder = newRecorder(src + '    ');
+      recorder..currentToken = chain([classKeyword(0),
+                                      identifier('A', 6),
+                                      openParen(8)])
+              ..advanceToken('class')
+              ..space()
+              ..advanceToken('A')
+              ..space()
+              ..advanceToken('{')
+              ..newline();
+
+      expect(doFormat(recorder).length, equals((src + NEW_LINE).length));
+    });
+
+
+  });
+
+
+  /// Edit operations
+  group('edit operations', () {
+
+    test('replace same length', () {
+      var edits = [new Edit(1, 2, 'oo'),
+                   new Edit(4, 5, 'bar')];
+      expect(new EditOperation().apply(edits, 'fun house'), equals('foo bar'));
+    });
+
+    test('replace shorten', () {
+      var edits = [new Edit(0, 2, 'a'),
+                   new Edit(2, 2, 'b'),
+                   new Edit(4, 2, 'c')];
+      expect(new EditOperation().apply(edits, 'AaBbCc'), equals('abc'));
+    });
+
+
   });
 
 
   /// Formatter tests
   group('formatter', () {
 
-    test('failedParse', () {
+    test('failed parse', () {
       var formatter = new CodeFormatter();
-      expect(() => formatter.format(CodeKind.COMPILATION_UNIT, "~"),
-                   throwsA(new isInstanceOf<FormatterException>('FE')));
+      expect(() => formatter.format(CodeKind.COMPILATION_UNIT, '~'),
+                   throwsA(new isInstanceOf<FormatterException>()));
     });
 
+    test('CU (1)', () {
+      expectCUFormatsTo(
+          'class A  {\n'
+          '}',
+          'class A {\n'
+          '}'
+        );
+    });
+
+    test('CU (2)', () {
+      expectCUFormatsTo(
+          'class      A  {  \n'
+          '}',
+          'class A {\n'
+          '}'
+        );
+    });
+
+    test('CU (3)', () {
+      expectCUFormatsTo(
+          'class A {\n'
+          '  }',
+          'class A {\n'
+          '}'
+        );
+    });
+
+    test('CU (4)', () {
+      expectCUFormatsTo(
+          ' class A {\n'
+          '}',
+          'class A {\n'
+          '}'
+        );
+    });
+
+    test('CU (method indent)', () {
+      expectCUFormatsTo(
+          'class A {\n'
+          'void x(){\n'
+          '}\n'
+          '}',
+          'class A {\n'
+          '  void x() {\n'
+          '  }\n'
+          '}'
+        );
+    });
+
+    test('CU (method indent - 2)', () {
+      expectCUFormatsTo(
+          'class A {\n'
+          ' static  void x(){}\n'
+          ' }',
+          'class A {\n'
+          '  static void x() {\n'
+          '  }\n'
+          '}'
+        );
+    });
+
+
+
 //    test('initialIndent', () {
-//      var formatter = new CodeFormatter(new Options(initialIndentationLevel:2));
+//      var formatter = new CodeFormatter(
+//          new FormatterOptions(initialIndentationLevel:2));
 //      var formattedSource = formatter.format(CodeKind.STATEMENT, 'var x;');
 //      expect(formattedSource, startsWith('  '));
 //    });
@@ -55,8 +218,32 @@
 
 }
 
-EditRecorder newRecorder(String source) {
-  var recorder = new EditRecorder(new FormatterOptions());
-  recorder.source = source;
-  return recorder;
+Token classKeyword(int offset) =>
+    new KeywordToken(Keyword.CLASS, offset);
+
+Token identifier(String value, int offset) =>
+    new StringToken(TokenType.IDENTIFIER, value, offset);
+
+Token openParen(int offset) =>
+    new StringToken(TokenType.OPEN_PAREN, '{', offset);
+
+Token closeParen(int offset) =>
+    new StringToken(TokenType.CLOSE_PAREN, '}', offset);
+
+Token chain(List<Token> tokens) {
+  for (var i = 0; i < tokens.length - 1; ++i) {
+    tokens[i].setNext(tokens[i + 1]);
+  }
+  return tokens[0];
 }
+
+EditRecorder newRecorder(source) =>
+    new EditRecorder(new FormatterOptions())..source = source;
+
+String doFormat(recorder) =>
+    new EditOperation().apply(recorder.editStore.edits, recorder.source);
+
+String formatCU(src, {options: const FormatterOptions()}) =>
+    new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src);
+
+expectCUFormatsTo(src, expected) => expect(formatCU(src), equals(expected));
diff --git a/pkg/analyzer_experimental/test/services/test_utils.dart b/pkg/analyzer_experimental/test/services/test_utils.dart
index 2128aaa..e8757a4 100644
--- a/pkg/analyzer_experimental/test/services/test_utils.dart
+++ b/pkg/analyzer_experimental/test/services/test_utils.dart
@@ -178,7 +178,7 @@
 
   bool exists() => true;
 
-  bool isInSystemLibrary() => _unsupported();
+  bool get isInSystemLibrary => _unsupported();
 
   Source resolve(String uri) => _unsupported();
 
diff --git a/pkg/args/lib/args.dart b/pkg/args/lib/args.dart
index 3898b9f..668577c 100644
--- a/pkg/args/lib/args.dart
+++ b/pkg/args/lib/args.dart
@@ -257,6 +257,8 @@
 
 import 'src/parser.dart';
 import 'src/usage.dart';
+import 'src/options.dart';
+export 'src/options.dart';
 
 /**
  * A class for taking a list of raw command line arguments and parsing out
@@ -345,9 +347,20 @@
   /**
    * Parses [args], a list of command-line arguments, matches them against the
    * flags and options defined by this parser, and returns the result.
+   *
+   * If [allowTrailingOptions] is set, the parser will continue parsing even
+   * after it finds an argument that is neither an option nor a command.
+   * This allows options to be specified after regular arguments.
+   *
+   * [allowTrailingOptions] is false by default, so when a non-option,
+   * non-command argument is encountered, it and all remaining arguments,
+   * even those that look like options are passed to the innermost command.
    */
-  ArgResults parse(List<String> args) =>
-      new Parser(null, this, args.toList()).parse();
+  ArgResults parse(List<String> args, {bool allowTrailingOptions}) {
+    if (allowTrailingOptions == null) allowTrailingOptions = false;
+    return new Parser(null, this, args.toList(), null, null,
+        allowTrailingOptions: allowTrailingOptions).parse();
+  }
 
   /**
    * Generates a string displaying usage information for the defined options.
@@ -377,52 +390,6 @@
 }
 
 /**
- * A command-line option. Includes both flags and options which take a value.
- */
-class Option {
-  final String name;
-  final String abbreviation;
-  final List<String> allowed;
-  final defaultValue;
-  final Function callback;
-  final String help;
-  final Map<String, String> allowedHelp;
-  final bool isFlag;
-  final bool negatable;
-  final bool allowMultiple;
-
-  Option(this.name, this.abbreviation, this.help, this.allowed,
-      this.allowedHelp, this.defaultValue, this.callback, {this.isFlag,
-      this.negatable, this.allowMultiple: false}) {
-
-    if (name.isEmpty) {
-      throw new ArgumentError('Name cannot be empty.');
-    } else if (name.startsWith('-')) {
-      throw new ArgumentError('Name $name cannot start with "-".');
-    }
-
-    // Ensure name does not contain any invalid characters.
-    if (_invalidChars.hasMatch(name)) {
-      throw new ArgumentError('Name "$name" contains invalid characters.');
-    }
-
-    if (abbreviation != null) {
-      if (abbreviation.length != 1) {
-        throw new ArgumentError('Abbreviation must be null or have length 1.');
-      } else if(abbreviation == '-') {
-        throw new ArgumentError('Abbreviation cannot be "-".');
-      }
-
-      if (_invalidChars.hasMatch(abbreviation)) {
-        throw new ArgumentError('Abbreviation is an invalid character.');
-      }
-    }
-  }
-
-  static final _invalidChars = new RegExp(r'''[ \t\r\n"'\\/]''');
-}
-
-/**
  * The results of parsing a series of command line arguments using
  * [ArgParser.parse()]. Includes the parsed options and any remaining unparsed
  * command line arguments.
diff --git a/pkg/args/lib/src/parser.dart b/pkg/args/lib/src/parser.dart
index d35f9ea..37a8e41 100644
--- a/pkg/args/lib/src/parser.dart
+++ b/pkg/args/lib/src/parser.dart
@@ -28,16 +28,26 @@
    */
   final Parser parent;
 
+  /** If `true`, parsing will continue after a non-option argument. */
+  final bool allowTrailingOptions;
+
   /** The grammar being parsed. */
   final ArgParser grammar;
 
   /** The arguments being parsed. */
   final List<String> args;
 
+  /** The remaining non-option, non-command arguments. */
+  final rest = <String>[];
+
   /** The accumulated parsed options. */
   final Map results = {};
 
-  Parser(this.commandName, this.grammar, this.args, [this.parent]);
+  Parser(this.commandName, this.grammar, this.args, this.parent, rest,
+      {this.allowTrailingOptions: false}) {
+    if (rest != null) this.rest.addAll(rest);
+  }
+
 
   /** The current argument being parsed. */
   String get current => args[0];
@@ -67,10 +77,15 @@
       // options so that commands can have option-like names.
       var command = grammar.commands[current];
       if (command != null) {
+        validate(rest.isEmpty, 'Cannot specify arguments before a command.');
         var commandName = args.removeAt(0);
-        var commandParser = new Parser(commandName, command, args, this);
+        var commandParser = new Parser(commandName, command, args, this, rest,
+            allowTrailingOptions: allowTrailingOptions);
         commandResults = commandParser.parse();
-        continue;
+
+        // All remaining arguments were passed to command so clear them here.
+        rest.clear();
+        break;
       }
 
       // Try to parse the current argument as an option. Note that the order
@@ -79,8 +94,10 @@
       if (parseAbbreviation(this)) continue;
       if (parseLongOption()) continue;
 
-      // If we got here, the argument doesn't look like an option, so stop.
-      break;
+      // This argument is neither option nor command, so stop parsing unless
+      // the [allowTrailingOptions] option is set.
+      if (!allowTrailingOptions) break;
+      rest.add(args.removeAt(0));
     }
 
     // Set unspecified multivalued arguments to their default value,
@@ -95,7 +112,7 @@
     });
 
     // Add in the leftover arguments we didn't parse to the innermost command.
-    var rest = args.toList();
+    rest.addAll(args);
     args.clear();
     return new ArgResults(results, commandName, commandResults, rest);
   }
diff --git a/pkg/args/test/parse_all_test.dart b/pkg/args/test/parse_all_test.dart
index a921046..8498ae6 100644
--- a/pkg/args/test/parse_all_test.dart
+++ b/pkg/args/test/parse_all_test.dart
@@ -8,55 +8,56 @@
 import 'package:args/args.dart';
 
 main() {
-  group('ArgParser.parse() starting with a non-option', () {
+  group('ArgParser.parse(allowTrailingOptions: true) '
+        'starting with a non-option', () {
     test('followed by flag', () {
       var parser = new ArgParser()..addFlag('flag');
       var args = ['A', '--flag'];
 
-      var results = parser.parse(args);
-      expect(results['flag'], isFalse);
-      expect(results.rest, orderedEquals(args));
+      var resultsAll = parser.parse(args, allowTrailingOptions: true);
+      expect(resultsAll['flag'], isTrue);
+      expect(resultsAll.rest, equals(['A']));
     });
 
     test('followed by option', () {
       var parser = new ArgParser()..addOption('opt');
       var args = ['A', '--opt'];
 
-      var results = parser.parse(args);
-      expect(results['opt'], isNull);
-      expect(results.rest, orderedEquals(args));
+      expectThrows(parser, args);
     });
 
     test('followed by option and value', () {
       var parser = new ArgParser()..addOption('opt');
       var args = ['A', '--opt', 'V'];
 
-      var results = parser.parse(args);
-      expect(results['opt'], isNull);
-      expect(results.rest, orderedEquals(args));
+      var resultsAll = parser.parse(args, allowTrailingOptions: true);
+      expect(resultsAll['opt'], equals('V'));
+      expect(resultsAll.rest, equals(['A']));
     });
 
     test('followed by unknown flag', () {
       var parser = new ArgParser();
       var args = ['A', '--xflag'];
-      var results = parser.parse(args);
-      expect(results.rest, orderedEquals(args));
+
+      expectThrows(parser, args);
     });
 
     test('followed by unknown option and value', () {
       var parser = new ArgParser();
       var args = ['A', '--xopt', 'V'];
-      var results = parser.parse(args);
-      expect(results.rest, orderedEquals(args));
+
+      expectThrows(parser, args);
     });
 
     test('followed by command', () {
       var parser = new ArgParser()..addCommand('com');
       var args = ['A', 'com'];
 
-      var results = parser.parse(args);
-      expect(results.command, isNull);
-      expect(results.rest, orderedEquals(args));
+      expectThrows(parser, args);
     });
   });
 }
+expectThrows(ArgParser parser, List<String> args) =>
+  expect(() => parser.parse(args, allowTrailingOptions: true),
+      throwsFormatException,
+      reason: "with allowTrailingOptions: true");
diff --git a/pkg/barback/lib/barback.dart b/pkg/barback/lib/barback.dart
new file mode 100644
index 0000000..8c3928e
--- /dev/null
+++ b/pkg/barback/lib/barback.dart
@@ -0,0 +1,12 @@
+// 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 barback;
+
+export 'src/asset.dart';
+export 'src/asset_id.dart';
+export 'src/asset_provider.dart';
+export 'src/errors.dart';
+export 'src/transform.dart' show Transform;
+export 'src/transformer.dart';
\ No newline at end of file
diff --git a/pkg/barback/lib/src/asset.dart b/pkg/barback/lib/src/asset.dart
new file mode 100644
index 0000000..2de733f
--- /dev/null
+++ b/pkg/barback/lib/src/asset.dart
@@ -0,0 +1,95 @@
+// 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 barback.asset;
+
+import 'dart:async';
+import 'dart:io';
+
+/// A blob of content.
+///
+/// Assets may come from the file system, or as the output of a [Transformer].
+/// They are identified by [AssetId].
+abstract class Asset {
+  factory Asset.fromFile(File file) {
+    return new _FileAsset(file);
+  }
+
+  factory Asset.fromString(String content) {
+    return new _StringAsset(content);
+  }
+
+  factory Asset.fromPath(String path) {
+    return new _FileAsset(new File(path));
+  }
+
+  // TODO(rnystrom): This prevents users from defining their own
+  // implementations of Asset. Use serialization package instead.
+  factory Asset.deserialize(data) {
+    // TODO(rnystrom): Handle errors.
+    switch (data[0]) {
+      case "file": return new _FileAsset(new File(data[1])); break;
+      case "string": return new _StringAsset(data[1]); break;
+    }
+  }
+
+  /// Returns the contents of the asset as a string.
+  // TODO(rnystrom): Figure out how binary assets should be handled.
+  String readAsString();
+
+  /// Streams the contents of the asset.
+  Stream<List<int>> read();
+
+  /// Serializes this [Asset] to an object that can be sent across isolates
+  /// and passed to [deserialize].
+  Object serialize();
+}
+
+/// An asset backed by a file on the local file system.
+class _FileAsset implements Asset {
+  final File _file;
+  _FileAsset(this._file);
+
+  String readAsString() => _file.readAsStringSync();
+  Stream<List<int>> read() => _file.openRead();
+
+  String toString() => 'File "${_file.path}"';
+
+  Object serialize() => ["file", _file.path];
+}
+
+/// An asset whose data is stored in a string.
+// TODO(rnystrom): Have something similar for in-memory binary assets.
+class _StringAsset implements Asset {
+  final String _contents;
+
+  _StringAsset(this._contents);
+
+  String readAsString() => _contents;
+
+  // TODO(rnystrom): Implement this and handle encoding.
+  Stream<List<int>> read() => throw new UnimplementedError();
+
+  String toString() {
+    // Don't show the whole string if it's long.
+    var contents = _contents;
+    if (contents.length > 40) {
+      contents = contents.substring(0, 20) + " ... " +
+                 contents.substring(contents.length - 20);
+    }
+
+    contents = _escape(contents);
+    return 'String "$contents"';
+  }
+
+  Object serialize() => ["string", _contents];
+
+  String _escape(String string) {
+    return string
+        .replaceAll("\"", r'\"')
+        .replaceAll("\n", r"\n")
+        .replaceAll("\r", r"\r")
+        .replaceAll("\t", r"\t");
+  }
+}
diff --git a/pkg/barback/lib/src/asset_graph.dart b/pkg/barback/lib/src/asset_graph.dart
new file mode 100644
index 0000000..a73b674
--- /dev/null
+++ b/pkg/barback/lib/src/asset_graph.dart
@@ -0,0 +1,225 @@
+// 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 barback.asset_graph;
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'asset.dart';
+import 'asset_id.dart';
+import 'asset_provider.dart';
+import 'errors.dart';
+import 'change_batch.dart';
+import 'phase.dart';
+import 'transformer.dart';
+
+/// The main build dependency manager.
+///
+/// For any given input file, it can tell which output files are affected by
+/// it, and vice versa.
+class AssetGraph {
+  final AssetProvider _provider;
+
+  final _phases = <Phase>[];
+
+  Stream<ProcessResult> get results => _resultsController.stream;
+  final _resultsController = new StreamController<ProcessResult>.broadcast();
+
+  /// A future that completes when the currently running build process finishes.
+  ///
+  /// If no build it in progress, is `null`.
+  Future _processDone;
+
+  ChangeBatch _sourceChanges;
+
+  /// Creates a new [AssetGraph].
+  ///
+  /// It loads source assets using [provider] and then uses [transformerPhases]
+  /// to generate output files from them.
+  //TODO(rnystrom): Better way of specifying transformers and their ordering.
+  AssetGraph(this._provider,
+      Iterable<Iterable<Transformer>> transformerPhases) {
+    // Flatten the phases to a list so we can traverse backwards to wire up
+    // each phase to its next.
+    transformerPhases = transformerPhases.toList();
+
+    // Each phase writes its outputs as inputs to the next phase after it.
+    // Add a phase at the end for the final outputs of the last phase.
+    transformerPhases.add([]);
+
+    Phase nextPhase = null;
+    for (var transformers in transformerPhases.reversed) {
+      nextPhase = new Phase(this, _phases.length, transformers.toList(),
+          nextPhase);
+      _phases.insert(0, nextPhase);
+    }
+  }
+
+  /// Gets the asset identified by [id].
+  ///
+  /// If [id] is for a generated or transformed asset, this will wait until
+  /// it has been created and return it. If the asset cannot be found, throws
+  /// [AssetNotFoundException].
+  Future<Asset> getAssetById(AssetId id) {
+    // TODO(rnystrom): Waiting for the entire build to complete is unnecessary
+    // in some cases. Should optimize:
+    // * [id] may be generated before the compilation is finished. We should
+    //   be able to quickly check whether there are any more in-place
+    //   transformations that can be run on it. If not, we can return it early.
+    // * If everything is compiled, something that didn't output [id] is
+    //   dirtied, and then [id] is requested, we can return it immediately,
+    //   since anything overwriting it at that point is an error.
+    // * If [id] has never been generated and all active transformers provide
+    //   metadata about the file names of assets it can emit, we can prove that
+    //   none of them can emit [id] and fail early.
+    return _waitForProcess().then((_) {
+      // Each phase's inputs are the outputs of the previous phase. Find the
+      // last phase that contains the asset. Since the last phase has no
+      // transformers, this will find the latest output for that id.
+
+      // TODO(rnystrom): Currently does not omit assets that are actually used
+      // as inputs for transformers. This means you can request and get an
+      // asset that should be "consumed" because it's used to generate the
+      // real asset you care about. Need to figure out how we want to handle
+      // that and what use cases there are related to it.
+      for (var i = _phases.length - 1; i >= 0; i--) {
+        var node = _phases[i].inputs[id];
+        if (node != null) {
+          // By the time we get here, the asset should have been built.
+          assert(node.asset != null);
+          return node.asset;
+        }
+      }
+
+      // Couldn't find it.
+      var error = new AssetNotFoundException(id);
+      reportError(error);
+      throw error;
+    });
+  }
+
+  /// Adds [sources] to the graph's known set of source assets.
+  ///
+  /// Begins applying any transforms that can consume any of the sources. If a
+  /// given source is already known, it is considered modified and all
+  /// transforms that use it will be re-applied.
+  void updateSources(Iterable<AssetId> sources) {
+    if (_sourceChanges == null) _sourceChanges = new ChangeBatch();
+    _sourceChanges.update(sources);
+
+    _waitForProcess();
+  }
+
+  /// Removes [removed] from the graph's known set of source assets.
+  void removeSources(Iterable<AssetId> removed) {
+    if (_sourceChanges == null) _sourceChanges = new ChangeBatch();
+    _sourceChanges.remove(removed);
+
+    _waitForProcess();
+  }
+
+  /// Reports a process result with the given error then throws it.
+  void reportError(error) {
+    _resultsController.add(new ProcessResult(error));
+  }
+
+  /// Starts the build process asynchronously if there is work to be done.
+  ///
+  /// Returns a future that completes with the background processing is done.
+  /// If there is no work to do, returns a future that completes immediately.
+  /// All errors that occur during processing will be caught (and routed to the
+  /// [results] stream) before they get to the returned future, so it is safe
+  /// to discard it.
+  Future _waitForProcess() {
+    if (_processDone != null) return _processDone;
+    return _processDone = _process().catchError((error) {
+      // If we get here, it's an unexpected error. Runtime errors like missing
+      // assets should be handled earlier. Errors from transformers or other
+      // external code that barback calls into should be caught at that API
+      // boundary.
+      //
+      // On the off chance we get here, pipe the error to the results stream
+      // as an error. That will let applications handle it without it appearing
+      // in the same path as "normal" errors that get reported.
+      _resultsController.addError(error);
+    }).whenComplete(() {
+      _processDone = null;
+      // Report the build completion.
+      // TODO(rnystrom): Put some useful data in here.
+      _resultsController.add(new ProcessResult());
+    });
+  }
+
+  /// Starts the background processing.
+  ///
+  /// Returns a future that completes when all assets have been processed.
+  Future _process() {
+    return _processSourceChanges().then((_) {
+      // Find the first phase that has work to do and do it.
+      var future;
+      for (var phase in _phases) {
+        future = phase.process();
+        if (future != null) break;
+      }
+
+      // If all phases are done and no new updates have come in, we're done.
+      if (future == null) {
+        // If changes have come in, start over.
+        if (_sourceChanges != null) return _process();
+
+        // Otherwise, everything is done.
+        return;
+      }
+
+      // Process that phase and then loop onto the next.
+      return future.then((_) => _process());
+    });
+  }
+
+  /// Processes the current batch of changes to source assets.
+  Future _processSourceChanges() {
+    // Always pump the event loop. This ensures a bunch of synchronous source
+    // changes are processed in a single batch even when the first one starts
+    // the build process.
+    return new Future(() {
+      if (_sourceChanges == null) return null;
+
+      // Take the current batch to ensure it doesn't get added to while we're
+      // processing it.
+      var changes = _sourceChanges;
+      _sourceChanges = null;
+
+      var updated = new Map<AssetId, Asset>();
+      var futures = [];
+      for (var id in changes.updated) {
+        // TODO(rnystrom): Catch all errors from provider and route to results.
+        futures.add(_provider.getAsset(id).then((asset) {
+          updated[id] = asset;
+        }).catchError((error) {
+          if (error is AssetNotFoundException) {
+            // Handle missing asset errors like regular missing assets.
+            reportError(error);
+          } else {
+            // It's an unexpected error, so rethrow it.
+            throw error;
+          }
+        }));
+      }
+
+      return Future.wait(futures).then((_) {
+        _phases.first.updateInputs(updated, changes.removed);
+      });
+    });
+  }
+}
+
+/// Used to report build results back from the asynchronous build process
+/// running in the background.
+class ProcessResult {
+  /// The error that occurred, or `null` if the result is not an error.
+  final error;
+
+  ProcessResult([this.error]);
+}
diff --git a/pkg/barback/lib/src/asset_id.dart b/pkg/barback/lib/src/asset_id.dart
new file mode 100644
index 0000000..f9e325c
--- /dev/null
+++ b/pkg/barback/lib/src/asset_id.dart
@@ -0,0 +1,91 @@
+// 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 barback.asset_id;
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:pathos/path.dart' as pathos;
+
+/// AssetIDs always use POSIX style paths regardless of the host platform.
+final _posix = new pathos.Builder(style: pathos.Style.posix);
+
+/// Identifies an asset within a package.
+class AssetId {
+  /// The name of the package containing this asset.
+  final String package;
+
+  /// The path to the asset relative to the root directory of [package].
+  ///
+  /// Source (i.e. read from disk) and generated (i.e. the output of a
+  /// [Transformer]) assets all have paths. Even intermediate assets that are
+  /// generated and then consumed by later transformations will still have
+  /// a path used to identify it.
+  ///
+  /// Asset paths always use forward slashes as path separators, regardless of
+  /// the host platform.
+  final String path;
+
+  /// Gets the file extension of the asset, if it has one, including the ".".
+  String get extension => pathos.extension(path);
+
+  /// Creates a new AssetId at [path] within [package].
+  AssetId(this.package, String path)
+      : path = _posix.normalize(path);
+
+  /// Parses an [AssetId] string of the form "package|path/to/asset.txt".
+  factory AssetId.parse(String description) {
+    var parts = description.split("|");
+    if (parts.length != 2) {
+      throw new FormatException('Could not parse "$description".');
+    }
+
+    if (parts[0].isEmpty) {
+      throw new FormatException(
+          'Cannot have empty package name in "$description".');
+    }
+
+    if (parts[1].isEmpty) {
+      throw new FormatException(
+          'Cannot have empty path in "$description".');
+    }
+
+    return new AssetId(parts[0], parts[1]);
+  }
+
+  /// Deserializes an [AssetId] from [data], which must be the result of
+  /// calling [serialize] on an existing [AssetId].
+  ///
+  /// Note that this is intended for communicating ids across isolates and not
+  /// for persistent storage of asset identifiers. There is no guarantee of
+  /// backwards compatibility in serialization form across versions.
+  AssetId.deserialize(data)
+      : package = data[0],
+        path = data[1];
+
+  /// Returns `true` of [other] is an [AssetId] with the same package and path.
+  operator ==(other) =>
+      other is AssetId &&
+      package == other.package &&
+      path == other.path;
+
+  int get hashCode => package.hashCode ^ path.hashCode;
+
+  /// Returns a new [AssetId] with the same [package] as this one and with the
+  /// [path] extended to include [extension].
+  AssetId addExtension(String extension) =>
+      new AssetId(package, "$path$extension");
+
+  /// Returns a new [AssetId] with the same [package] and [path] as this one
+  /// but with file extension [newExtension].
+  AssetId changeExtension(String newExtension) =>
+      new AssetId(package, pathos.withoutExtension(path) + newExtension);
+
+  String toString() => "$package|$path";
+
+  /// Serializes this [AssetId] to an object that can be sent across isolates
+  /// and passed to [deserialize].
+  serialize() => [package, path];
+}
diff --git a/pkg/barback/lib/src/asset_node.dart b/pkg/barback/lib/src/asset_node.dart
new file mode 100644
index 0000000..6fd86c6
--- /dev/null
+++ b/pkg/barback/lib/src/asset_node.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library barback.asset_node;
+
+import 'dart:async';
+
+import 'asset.dart';
+import 'asset_graph.dart';
+import 'asset_id.dart';
+import 'phase.dart';
+import 'transform_node.dart';
+
+/// Describes an asset and its relationship to the build dependency graph.
+///
+/// Keeps a cache of the last asset that was built for this node (i.e. for this
+/// node's ID and phase) and tracks which transforms depend on it.
+class AssetNode {
+  final AssetId id;
+  Asset asset;
+
+  /// The [TransformNode]s that consume this node's asset as an input.
+  final consumers = new Set<TransformNode>();
+
+  AssetNode(this.id);
+
+  /// Updates this node's generated asset value and marks all transforms that
+  /// use this as dirty.
+  void updateAsset(Asset asset) {
+    this.asset = asset;
+    consumers.forEach((consumer) => consumer.dirty());
+  }
+}
diff --git a/pkg/barback/lib/src/asset_provider.dart b/pkg/barback/lib/src/asset_provider.dart
new file mode 100644
index 0000000..565e5ac
--- /dev/null
+++ b/pkg/barback/lib/src/asset_provider.dart
@@ -0,0 +1,32 @@
+// 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 barback.asset_provider;
+
+import 'dart:async';
+
+import 'asset.dart';
+import 'asset_id.dart';
+
+/// API for locating and accessing packages on disk.
+///
+/// Implemented by pub and provided to barback so that it isn't coupled
+/// directly to pub.
+abstract class AssetProvider {
+  /// The names of all packages that can be provided by this provider.
+  ///
+  /// This is equal to the transitive closure of the entrypoint package
+  /// dependencies.
+  Iterable<String> get packages;
+
+  // TODO(rnystrom): Make this async.
+  /// The paths of all available asset files in [package], relative to the
+  /// package's root directory.
+  ///
+  /// You can pass [within], which should be the relative path to a directory
+  /// within the package, to only return the files within that subdirectory.
+  List<AssetId> listAssets(String package, {String within});
+
+  Future<Asset> getAsset(AssetId id);
+}
diff --git a/pkg/barback/lib/src/change_batch.dart b/pkg/barback/lib/src/change_batch.dart
new file mode 100644
index 0000000..aa2a1c4
--- /dev/null
+++ b/pkg/barback/lib/src/change_batch.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library barback.change_batch;
+
+import 'asset.dart';
+import 'asset_id.dart';
+
+/// Represents a batch of source asset changes: additions, removals and
+/// modifications.
+class ChangeBatch {
+  /// The assets that have been added or modified in this batch.
+  final updated = new Set<AssetId>();
+
+  /// The assets that have been removed in this batch.
+  final removed = new Set<AssetId>();
+
+  /// Adds the updated [assets] to this batch.
+  void update(Iterable<AssetId> assets) {
+    updated.addAll(assets);
+
+    // If they were previously removed, they are back now.
+    removed.removeAll(assets);
+  }
+
+  /// Removes [assets] from this batch.
+  void remove(Iterable<AssetId> assets) {
+    removed.addAll(assets);
+
+    // If they were previously updated, they are gone now.
+    updated.removeAll(assets);
+  }
+}
diff --git a/pkg/barback/lib/src/errors.dart b/pkg/barback/lib/src/errors.dart
new file mode 100644
index 0000000..65dcad6
--- /dev/null
+++ b/pkg/barback/lib/src/errors.dart
@@ -0,0 +1,38 @@
+// 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 barback.errors;
+
+import 'dart:async';
+import 'dart:io';
+
+import 'asset_id.dart';
+
+/// Error thrown when an asset with [id] cannot be found.
+class AssetNotFoundException implements Exception {
+  final AssetId id;
+
+  AssetNotFoundException(this.id);
+
+  String toString() => "Could not find asset $id.";
+}
+
+/// Error thrown when two transformers both output an asset with [id].
+class AssetCollisionException implements Exception {
+  final AssetId id;
+
+  AssetCollisionException(this.id);
+
+  String toString() => "Got collision on asset $id.";
+}
+
+/// Error thrown when a transformer requests an input [id] which cannot be
+/// found.
+class MissingInputException implements Exception {
+  final AssetId id;
+
+  MissingInputException(this.id);
+
+  String toString() => "Missing input $id.";
+}
diff --git a/pkg/barback/lib/src/phase.dart b/pkg/barback/lib/src/phase.dart
new file mode 100644
index 0000000..d52ed75
--- /dev/null
+++ b/pkg/barback/lib/src/phase.dart
@@ -0,0 +1,184 @@
+// 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 barback.phase;
+
+import 'dart:async';
+
+import 'asset.dart';
+import 'asset_graph.dart';
+import 'asset_id.dart';
+import 'asset_node.dart';
+import 'errors.dart';
+import 'transform_node.dart';
+import 'transformer.dart';
+
+/// One phase in the ordered series of transformations in an [AssetGraph].
+///
+/// Each phase can access outputs from previous phases and can in turn pass
+/// outputs to later phases. Phases are processed strictly serially. All
+/// transforms in a phase will be complete before moving on to the next phase.
+/// Within a single phase, all transforms will be run in parallel.
+///
+/// Building can be interrupted between phases. For example, a source is added
+/// which starts the background process. Sometime during, say, phase 2 (which
+/// is running asynchronously) that source is modified. When the process queue
+/// goes to advance to phase 3, it will see that modification and start the
+/// waterfall from the beginning again.
+class Phase {
+  /// The graph that owns this phase.
+  final AssetGraph graph;
+
+  /// This phase's position relative to the other phases. Zero-based.
+  final int _index;
+
+  /// The transformers that can access [inputs].
+  ///
+  /// Their outputs will be available to the next phase.
+  final List<Transformer> _transformers;
+
+  /// The inputs that are available for transforms in this phase to consume.
+  ///
+  /// For the first phase, these will be the source assets. For all other
+  /// phases, they will be the outputs from the previous phase.
+  final inputs = new Map<AssetId, AssetNode>();
+
+  /// The transforms currently applicable to assets in [inputs].
+  ///
+  /// These are the transforms that have been "wired up": they represent a
+  /// repeatable transformation of a single concrete set of inputs. "dart2js"
+  /// is a transformer. "dart2js on web/main.dart" is a transform.
+  final _transforms = new Set<TransformNode>();
+
+  /// The nodes that are new in this phase since the last time [process] was
+  /// called.
+  ///
+  /// When we process, we'll check these to see if we can hang new transforms
+  /// off them.
+  final _newInputs = new Set<AssetNode>();
+
+  /// The phase after this one.
+  ///
+  /// Outputs from this phase will be passed to it.
+  final Phase _next;
+
+  Phase(this.graph, this._index, this._transformers, this._next);
+
+  /// Updates the phase's inputs with [updated] and removes [removed].
+  ///
+  /// This marks any affected [transforms] as dirty or discards them if their
+  /// inputs are removed.
+  void updateInputs(Map<AssetId, Asset> updated, Set<AssetId> removed) {
+    // Remove any nodes that are no longer being output. Handle removals first
+    // in case there are assets that were removed by one transform but updated
+    // by another. In that case, the update should win.
+    for (var id in removed) {
+      var node = inputs.remove(id);
+
+      // Every transform that was using it is dirty now.
+      if (node != null) {
+        node.consumers.forEach((consumer) => consumer.dirty());
+      }
+    }
+
+    // Update and new or modified assets.
+    updated.forEach((id, asset) {
+      var node = inputs.putIfAbsent(id, () => new AssetNode(id));
+
+      // If it's a new node, remember that so we can see if any new transforms
+      // will consume it.
+      if (node.asset == null) _newInputs.add(node);
+
+      node.updateAsset(asset);
+    });
+  }
+
+  /// Processes this phase.
+  ///
+  /// For all new inputs, it tries to see if there are transformers that can
+  /// consume them. Then all applicable transforms are applied.
+  ///
+  /// Returns a future that completes when processing is done. If there is
+  /// nothing to process, returns `null`.
+  Future process() {
+    var future = _processNewInputs();
+    if (future == null) {
+      return _processTransforms();
+    }
+
+    return future.then((_) => _processTransforms());
+  }
+
+  /// Creates new transforms for any new inputs that are applicable.
+  Future _processNewInputs() {
+    if (_newInputs.isEmpty) return null;
+
+    var futures = [];
+    for (var node in _newInputs) {
+      for (var transformer in _transformers) {
+        // TODO(rnystrom): Catch all errors from isPrimary() and redirect
+        // to results.
+        futures.add(transformer.isPrimary(node.id).then((isPrimary) {
+          if (!isPrimary) return;
+          var transform = new TransformNode(this, transformer, node);
+          node.consumers.add(transform);
+          _transforms.add(transform);
+        }));
+      }
+    }
+
+    _newInputs.clear();
+
+    return Future.wait(futures);
+  }
+
+  /// Applies all currently wired up and dirty transforms.
+  ///
+  /// Passes their outputs to the next phase.
+  Future _processTransforms() {
+    var dirtyTransforms = _transforms.where((transform) => transform.isDirty);
+    if (dirtyTransforms.isEmpty) return null;
+
+    return Future.wait(dirtyTransforms.map((transform) => transform.apply()))
+        .then((transformOutputs) {
+      // Collect all of the outputs. Since the transforms are run in parallel,
+      // we have to be careful here to ensure that the result is deterministic
+      // and not influenced by the order that transforms complete.
+      var updated = new Map<AssetId, Asset>();
+      var removed = new Set<AssetId>();
+      var collisions = new Set<AssetId>();
+
+      // Handle the generated outputs of all transforms first.
+      for (var outputs in transformOutputs) {
+        // Collect the outputs of all transformers together.
+        outputs.updated.forEach((id, asset) {
+          if (updated.containsKey(id)) {
+            // Report a collision.
+            collisions.add(id);
+          } else {
+            // TODO(rnystrom): In the case of a collision, the asset that
+            // "wins" is chosen non-deterministically. Do something better.
+            updated[id] = asset;
+          }
+        });
+
+        // Track any assets no longer output by this transform. We don't
+        // handle the case where *another* transform generates the asset
+        // no longer generated by this one. updateInputs() handles that.
+        removed.addAll(outputs.removed);
+      }
+
+      // Report any collisions in deterministic order.
+      collisions = collisions.toList();
+      collisions.sort((a, b) => a.toString().compareTo(b.toString()));
+      for (var collision in collisions) {
+        graph.reportError(new AssetCollisionException(collision));
+        // TODO(rnystrom): Define what happens after a collision occurs.
+      }
+
+      // Pass the outputs to the next phase.
+      _next.updateInputs(updated, removed);
+    });
+  }
+}
diff --git a/pkg/barback/lib/src/transform.dart b/pkg/barback/lib/src/transform.dart
new file mode 100644
index 0000000..8023d0e
--- /dev/null
+++ b/pkg/barback/lib/src/transform.dart
@@ -0,0 +1,79 @@
+// 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 barback.transform;
+
+import 'dart:async';
+
+import 'asset.dart';
+import 'asset_id.dart';
+import 'asset_node.dart';
+import 'errors.dart';
+import 'transform_node.dart';
+
+/// Creates a [Transform] by forwarding to the private constructor.
+///
+/// Lets [TransformNode] create [Transforms] without giving a [Transform]
+/// itself a public constructor, which would be visible to external users.
+/// Unlike the [Transform] class, this function is not exported by barback.dart.
+Transform createTransform(TransformNode node, Set<AssetNode> inputs,
+                          Map<AssetId, Asset> outputs) =>
+    new Transform._(node, inputs, outputs);
+
+/// While a [Transformer] represents a *kind* of transformation, this defines
+/// one specific usage of it on a set of files.
+///
+/// This ephemeral object exists only during an actual transform application to
+/// facilitate communication between the [Transformer] and the code hosting
+/// the transformation. It lets the [Transformer] access inputs and generate
+/// outputs.
+class Transform {
+  final TransformNode _node;
+
+  final Set<AssetNode> _inputs;
+  final Map<AssetId, Asset> _outputs;
+
+  /// Gets the ID of the primary input for this transformation.
+  ///
+  /// While a transformation can use multiple input assets, one must be a
+  /// special "primary" asset. This will be the "entrypoint" or "main" input
+  /// file for a transformation.
+  ///
+  /// For example, with a dart2js transform, the primary input would be the
+  /// entrypoint Dart file. All of the other Dart files that that imports
+  /// would be secondary inputs.
+  AssetId get primaryId => _node.primary.id;
+
+  /// Gets the asset for the primary input.
+  Future<Asset> get primaryInput => getInput(primaryId);
+
+  Transform._(this._node, this._inputs, this._outputs);
+
+  /// Gets the asset for for an input [id].
+  ///
+  /// If an input with that ID cannot be found, throws an
+  /// [AssetNotFoundException].
+  Future<Asset> getInput(AssetId id) {
+    return new Future(() {
+      var node = _node.phase.inputs[id];
+      // TODO(rnystrom): Need to handle passthrough where an asset from a
+      // previous phase can be found.
+
+      // Throw if the input isn't found. This ensures the transformer's apply
+      // is exited. We'll then catch this and report it through the proper
+      // results stream.
+      if (node == null) throw new MissingInputException(id);
+
+      // Keep track of which assets this transform depends on.
+      _inputs.add(node);
+      return node.asset;
+    });
+  }
+
+  /// Stores [output] as the output created by this transformation for asset
+  /// [id]. A transformation can output as many assets as it wants.
+  void addOutput(AssetId id, Asset output) {
+    _outputs[id] = output;
+  }
+}
diff --git a/pkg/barback/lib/src/transform_node.dart b/pkg/barback/lib/src/transform_node.dart
new file mode 100644
index 0000000..49222be
--- /dev/null
+++ b/pkg/barback/lib/src/transform_node.dart
@@ -0,0 +1,107 @@
+// 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 barback.transform_node;
+
+import 'dart:async';
+
+import 'asset.dart';
+import 'asset_graph.dart';
+import 'asset_id.dart';
+import 'asset_node.dart';
+import 'errors.dart';
+import 'phase.dart';
+import 'transform.dart';
+import 'transformer.dart';
+
+/// Describes a transform on a set of assets and its relationship to the build
+/// dependency graph.
+///
+/// Keeps track of whether it's dirty and needs to be run and which assets it
+/// depends on.
+class TransformNode {
+  /// The [Phase] that this transform runs in.
+  final Phase phase;
+
+  /// The [Transformer] to apply to this node's inputs.
+  final Transformer _transformer;
+
+  /// The node for the primary asset this transform depends on.
+  final AssetNode primary;
+
+  /// True if an input has been modified since the last time this transform
+  /// was run.
+  bool get isDirty => _isDirty;
+  var _isDirty = true;
+
+  /// The inputs read by this transform the last time it was run.
+  ///
+  /// Used to tell if an input was removed in a later run.
+  var _inputs = new Set<AssetNode>();
+
+  /// The outputs created by this transform the last time it was run.
+  ///
+  /// Used to tell if an output was removed in a later run.
+  var _outputs = new Set<AssetId>();
+
+  TransformNode(this.phase, this._transformer, this.primary);
+
+  /// Marks this transform as needing to be run.
+  void dirty() {
+    _isDirty = true;
+  }
+
+  /// Applies this transform.
+  ///
+  /// Returns a [TransformOutputs] describing the resulting outputs compared to
+  /// previous runs.
+  Future<TransformOutputs> apply() {
+    var newInputs = new Set<AssetNode>();
+    var newOutputs = new Map<AssetId, Asset>();
+    var transform = createTransform(this, newInputs, newOutputs);
+    return _transformer.apply(transform).catchError((error) {
+      // Catch all transformer errors and pipe them to the results stream.
+      // This is so a broken transformer doesn't take down the whole graph.
+      phase.graph.reportError(error);
+
+      // Don't allow partial results from a failed transform.
+      newOutputs.clear();
+    }).then((_) {
+      _isDirty = false;
+
+      // Stop watching any inputs that were removed.
+      for (var oldInput in _inputs) {
+        oldInput.consumers.remove(this);
+      }
+
+      // Watch any new inputs so this transform will be re-processed when an
+      // input is modified.
+      for (var newInput in newInputs) {
+        newInput.consumers.add(this);
+      }
+
+      _inputs = newInputs;
+
+      // See which outputs are missing from the last run.
+      var outputIds = newOutputs.keys.toSet();
+      var removed = _outputs.difference(outputIds);
+      _outputs = outputIds;
+
+      return new TransformOutputs(newOutputs, removed);
+    });
+  }
+}
+
+/// The result of running a [Transform], compared to the previous time it was
+/// applied.
+class TransformOutputs {
+  /// The outputs that are new or were modified since the last run.
+  final Map<AssetId, Asset> updated;
+
+  /// The outputs that were created by the previous run but were not generated
+  /// by the most recent run.
+  final Set<AssetId> removed;
+
+  TransformOutputs(this.updated, this.removed);
+}
diff --git a/pkg/barback/lib/src/transformer.dart b/pkg/barback/lib/src/transformer.dart
new file mode 100644
index 0000000..664d2e4
--- /dev/null
+++ b/pkg/barback/lib/src/transformer.dart
@@ -0,0 +1,48 @@
+// 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 barback.transformer;
+
+import 'dart:async';
+import 'dart:io';
+
+import 'asset_id.dart';
+import 'transform.dart';
+
+/// A [Transformer] represents a processor that takes in one or more input
+/// assets and uses them to generate one or more output assets.
+///
+/// Dart2js, a SASS->CSS processor, a CSS spriter, and a tool to concatenate
+/// files are all examples of transformers. To define your own transformation
+/// step, extend (or implement) this class.
+abstract class Transformer {
+  /// Returns `true` if [input] can be a primary input for this transformer.
+  ///
+  /// While a transformer can read from multiple input files, one must be the
+  /// "primary" input. This asset determines whether the transformation should
+  /// be run at all. If the primary input is removed, the transformer will no
+  /// longer be run.
+  ///
+  /// A concrete example is dart2js. When you run dart2js, it will traverse
+  /// all of the imports in your Dart source files and use the contents of all
+  /// of those to generate the final JS. However you still run dart2js "on" a
+  /// single file: the entrypoint Dart file that has your `main()` method.
+  /// This entrypoint file would be the primary input.
+  Future<bool> isPrimary(AssetId input);
+
+  /// Run this transformer on on the primary input specified by [transform].
+  ///
+  /// The [transform] is used by the [Transformer] for two purposes (in
+  /// addition to accessing the primary input). It can call `getInput()` to
+  /// request additional input assets. It also calls `addOutput()` to provide
+  /// generated assets back to the system. Either can be called multiple times,
+  /// in any order.
+  ///
+  /// In other words, a Transformer's job is to find all inputs for a
+  /// transform, starting at the primary input, then generate all output assets
+  /// and yield them back to the transform.
+  Future apply(Transform transform);
+
+  String toString() => runtimeType.toString().replaceAll("Transformer", "");
+}
diff --git a/pkg/barback/pubspec.yaml b/pkg/barback/pubspec.yaml
new file mode 100644
index 0000000..903fa41
--- /dev/null
+++ b/pkg/barback/pubspec.yaml
@@ -0,0 +1,17 @@
+name: barback
+author: "Dart Team <misc@dartlang.org>"
+homepage: http://www.dartlang.org
+description: >
+  An asset build system.
+
+  Given a set of input files and a set of transformations (think compilers,
+  preprocessors and the like), will automatically apply the appropriate
+  transforms and generate output files. When inputs are modified, automatically
+  runs the transforms that are affected.
+
+  Runs transforms asynchronously and in parallel when possible to maximize
+  responsiveness.
+dependencies:
+  pathos: any
+dev_dependencies:
+  scheduled_test: any
diff --git a/pkg/barback/test/asset_graph/errors_test.dart b/pkg/barback/test/asset_graph/errors_test.dart
new file mode 100644
index 0000000..45a36de
--- /dev/null
+++ b/pkg/barback/test/asset_graph/errors_test.dart
@@ -0,0 +1,220 @@
+// 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 barback.test.asset_graph.source_test;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+import 'package:barback/src/asset_graph.dart';
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../utils.dart';
+
+main() {
+  initConfig();
+
+  test("errors if two transformers output the same file", () {
+    var provider = new MockProvider(["app|foo.a"]);
+    var graph = new AssetGraph(provider, [
+      [
+        new RewriteTransformer("a", "b"),
+        new RewriteTransformer("a", "b")
+      ]
+    ]);
+    graph.updateSources([new AssetId.parse("app|foo.a")]);
+
+    expectCollision(graph, "app|foo.b");
+  });
+
+  test("reports asset not found errors in results", () {
+    var provider = new MockProvider([]);
+    var graph = new AssetGraph(provider, []);
+
+    // TODO(rnystrom): This is verbose and ugly. Better would be to have
+    // utils.dart register this on the graph and then have functions to expect
+    // certain build results.
+    var numResults = 0;
+    var gotError = false;
+    graph.results.listen(wrapAsync((result) {
+      numResults++;
+      expect(numResults, lessThan(3));
+
+      if (numResults == 1) {
+        // Should complete the build first.
+        expect(result.error, isNull);
+      } else if (numResults == 2) {
+        // Then have the error.
+        expect(result.error, new isInstanceOf<AssetNotFoundException>());
+        expect(result.error.id, equals(new AssetId.parse("app|foo.txt")));
+        gotError = true;
+      }
+    }));
+
+    expectNoAsset(graph, "app|foo.txt");
+
+    schedule(() {
+      expect(gotError, isTrue);
+    });
+  });
+
+  test("reports an error for an unprovided source", () {
+    var provider = new MockProvider([]);
+    var graph = new AssetGraph(provider, []);
+    var resultFuture = graph.results.first;
+
+    graph.updateSources([new AssetId.parse("app|unknown.txt")]);
+
+    schedule(() {
+      return resultFuture.then((result) {
+        expect(result.error, new isInstanceOf<AssetNotFoundException>());
+        expect(result.error.id, equals(new AssetId.parse("app|unknown.txt")));
+      });
+    });
+  });
+
+  test("reports missing input errors in results", () {
+    var provider = new MockProvider({"app|a.txt": "a.inc"});
+
+    var graph = new AssetGraph(provider, [
+      [new ManyToOneTransformer("txt")]
+    ]);
+
+    var gotError = false;
+    graph.results.listen(wrapAsync((result) {
+      expect(result.error is MissingInputException, isTrue);
+      expect(result.error.id, equals(new AssetId.parse("app|a.inc")));
+      gotError = true;
+    }));
+
+    graph.updateSources([new AssetId.parse("app|a.txt")]);
+
+    expectNoAsset(graph, "app|a.out");
+
+    schedule(() {
+      expect(gotError, isTrue);
+    });
+  });
+
+  test("fails if a non-primary input is removed", () {
+    var provider = new MockProvider({
+      "app|a.txt": "a.inc,b.inc,c.inc",
+      "app|a.inc": "a",
+      "app|b.inc": "b",
+      "app|c.inc": "c"
+    });
+
+    var graph = new AssetGraph(provider, [
+      [new ManyToOneTransformer("txt")]
+    ]);
+
+    // TODO(rnystrom): This is verbose and ugly. Better would be to have
+    // utils.dart register this on the graph and then have functions to expect
+    // certain build results.
+    var numResults = 0;
+    var gotError = false;
+    graph.results.listen(wrapAsync((result) {
+      numResults++;
+      expect(numResults, lessThan(3));
+
+      if (numResults == 1) {
+        // Should complete the build first.
+        expect(result.error, isNull);
+      } else if (numResults == 2) {
+        // Then have the error.
+        expect(result.error is MissingInputException, isTrue);
+        expect(result.error.id, equals(new AssetId.parse("app|b.inc")));
+        gotError = true;
+      }
+    }));
+
+    graph.updateSources([
+      new AssetId.parse("app|a.txt"),
+      new AssetId.parse("app|a.inc"),
+      new AssetId.parse("app|b.inc"),
+      new AssetId.parse("app|c.inc")
+    ]);
+
+    expectAsset(graph, "app|a.out", "abc");
+
+    schedule(() {
+      graph.removeSources([new AssetId.parse("app|b.inc")]);
+    });
+
+    expectNoAsset(graph, "app|a.out");
+
+    schedule(() {
+      expect(gotError, isTrue);
+    });
+  });
+
+  test("catches transformer exceptions and reports them", () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var graph = new AssetGraph(provider, [
+      [new BadTransformer(["app|foo.out"])]
+    ]);
+
+    var gotError = false;
+    graph.results.listen(wrapAsync((result) {
+      expect(result.error, equals(BadTransformer.ERROR));
+      gotError = true;
+    }));
+
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|foo.txt")]);
+    });
+
+    expectNoAsset(graph, "app|foo.out");
+
+    schedule(() {
+      expect(gotError, isTrue);
+    });
+  });
+
+  // TODO(rnystrom): Is this the behavior we expect? If a transformer fails
+  // to transform a file, should we just skip past it to the source?
+  test("yields a source if a transform fails on it", () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var graph = new AssetGraph(provider, [
+      [new BadTransformer(["app|foo.txt"])]
+    ]);
+
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|foo.txt")]);
+    });
+
+    expectAsset(graph, "app|foo.txt");
+  });
+
+  test("catches errors even if nothing is waiting for process results", () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var graph = new AssetGraph(provider, [[new BadTransformer([])]]);
+    var resultFuture = graph.results.first;
+
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|foo.txt")]);
+    });
+
+    // Note: No asset requests here.
+
+    schedule(() {
+      return resultFuture.then((result) {
+        expect(result.error, equals(BadTransformer.ERROR));
+      });
+    });
+  });
+
+  test("discards outputs from failed transforms", () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var graph = new AssetGraph(provider, [
+      [new BadTransformer(["a.out", "b.out"])]
+    ]);
+
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|foo.txt")]);
+    });
+
+    expectNoAsset(graph, "app|a.out");
+  });
+}
diff --git a/pkg/barback/test/asset_graph/source_test.dart b/pkg/barback/test/asset_graph/source_test.dart
new file mode 100644
index 0000000..32d7f3d
--- /dev/null
+++ b/pkg/barback/test/asset_graph/source_test.dart
@@ -0,0 +1,170 @@
+// 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 barback.test.asset_graph.source_test;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+import 'package:barback/src/asset_graph.dart';
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../utils.dart';
+
+main() {
+  initConfig();
+  test("gets a source asset", () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var graph = new AssetGraph(provider, []);
+    graph.updateSources([new AssetId.parse("app|foo.txt")]);
+
+    expectAsset(graph, "app|foo.txt");
+  });
+
+  test("doesn't get an unknown source", () {
+    var provider = new MockProvider([]);
+    var graph = new AssetGraph(provider, []);
+
+    expectNoAsset(graph, "app|unknown.txt");
+  });
+
+  test("doesn't get an unprovided source", () {
+    var provider = new MockProvider([]);
+    var graph = new AssetGraph(provider, []);
+
+    graph.updateSources([new AssetId.parse("app|unknown.txt")]);
+    expectNoAsset(graph, "app|unknown.txt");
+  });
+
+  test("doesn't get an asset that isn't an updated source", () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var graph = new AssetGraph(provider, []);
+
+    // Sources must be explicitly made visible to barback by calling
+    // updateSources() on them. It isn't enough for the provider to be able
+    // to provide it.
+    //
+    // This lets you distinguish between sources that you want to be primaries
+    // and the larger set of inputs that those primaries are allowed to pull in.
+    expectNoAsset(graph, "app|foo.txt");
+  });
+
+  test("gets a source asset if not transformed", () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var graph = new AssetGraph(provider, [
+      [new RewriteTransformer("nottxt", "whatever")]
+    ]);
+    graph.updateSources([new AssetId.parse("app|foo.txt")]);
+
+    expectAsset(graph, "app|foo.txt");
+  });
+
+  test("doesn't get a removed source", () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var graph = new AssetGraph(provider, [[]]);
+    graph.updateSources([new AssetId.parse("app|foo.txt")]);
+
+    expectAsset(graph, "app|foo.txt");
+
+    schedule(() {
+      graph.removeSources([new AssetId.parse("app|foo.txt")]);
+    });
+
+    expectNoAsset(graph, "app|foo.txt");
+  });
+
+  test("collapses redundant updates", () {
+    var provider = new MockProvider(["app|foo.blub"]);
+    var transformer = new RewriteTransformer("blub", "blab");
+    var graph = new AssetGraph(provider, [[transformer]]);
+
+    schedule(() {
+      // Make a bunch of synchronous update calls.
+      graph.updateSources([new AssetId.parse("app|foo.blub")]);
+      graph.updateSources([new AssetId.parse("app|foo.blub")]);
+      graph.updateSources([new AssetId.parse("app|foo.blub")]);
+      graph.updateSources([new AssetId.parse("app|foo.blub")]);
+    });
+
+    expectAsset(graph, "app|foo.blab", "foo.blab");
+
+    schedule(() {
+      expect(transformer.numRuns, equals(1));
+    });
+  });
+
+  test("a removal cancels out an update", () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var graph = new AssetGraph(provider, [[]]);
+
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|foo.txt")]);
+      graph.removeSources([new AssetId.parse("app|foo.txt")]);
+    });
+
+    expectNoAsset(graph, "app|foo.txt");
+  });
+
+  test("an update cancels out a removal", () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var graph = new AssetGraph(provider, [[]]);
+
+    schedule(() {
+      graph.removeSources([new AssetId.parse("app|foo.txt")]);
+      graph.updateSources([new AssetId.parse("app|foo.txt")]);
+    });
+
+    expectAsset(graph, "app|foo.txt");
+  });
+
+  test("restarts a build if a source is updated while sources are loading", () {
+    var provider = new MockProvider(["app|foo.txt", "app|other.bar"]);
+    var transformer = new RewriteTransformer("txt", "out");
+    var graph = new AssetGraph(provider, [[transformer]]);
+
+    var numBuilds = 0;
+    var buildCompleter = new Completer();
+    graph.results.listen(wrapAsync((result) {
+      expect(result.error, isNull);
+      numBuilds++;
+
+      // There should be two builds, one for each update call.
+      if (numBuilds == 2) buildCompleter.complete();
+    }));
+
+    // Run the whole graph so all nodes are clean.
+    graph.updateSources([
+      new AssetId.parse("app|foo.txt"),
+      new AssetId.parse("app|other.bar")
+    ]);
+    expectAsset(graph, "app|foo.out", "foo.out");
+    expectAsset(graph, "app|other.bar");
+
+    schedule(() {
+      // Make the provider slow to load a source.
+      provider.wait();
+
+      // Update an asset that doesn't trigger any transformers.
+      graph.updateSources([new AssetId.parse("app|other.bar")]);
+    });
+
+    schedule(() {
+      // Now update an asset that does trigger a transformer.
+      graph.updateSources([new AssetId.parse("app|foo.txt")]);
+    });
+
+    schedule(() {
+      provider.complete();
+    });
+
+    schedule(() {
+      // Wait until the build has completed.
+      return buildCompleter.future;
+    });
+
+    schedule(() {
+      expect(transformer.numRuns, equals(2));
+    });
+  });
+}
diff --git a/pkg/barback/test/asset_graph/transform_test.dart b/pkg/barback/test/asset_graph/transform_test.dart
new file mode 100644
index 0000000..198f18e
--- /dev/null
+++ b/pkg/barback/test/asset_graph/transform_test.dart
@@ -0,0 +1,406 @@
+// 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 barback.test.asset_graph.transform_test;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+import 'package:barback/src/asset_graph.dart';
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../utils.dart';
+
+main() {
+  initConfig();
+  test("gets a transformed asset with a different path", () {
+    var provider = new MockProvider(["app|foo.blub"]);
+    var graph = new AssetGraph(provider, [
+      [new RewriteTransformer("blub", "blab")]
+    ]);
+    graph.updateSources([new AssetId.parse("app|foo.blub")]);
+
+    expectAsset(graph, "app|foo.blab", "foo.blab");
+  });
+
+  test("gets a transformed asset with the same path", () {
+    var provider = new MockProvider(["app|foo.blub"]);
+    var graph = new AssetGraph(provider, [
+      [new RewriteTransformer("blub", "blub")]
+    ]);
+    graph.updateSources([new AssetId.parse("app|foo.blub")]);
+
+    expectAsset(graph, "app|foo.blub", "foo.blub");
+  });
+
+  test("doesn't find an output from a later phase", () {
+    var provider = new MockProvider(["app|foo.a"]);
+    var graph = new AssetGraph(provider, [
+      [new RewriteTransformer("b", "c")],
+      [new RewriteTransformer("a", "b")]
+    ]);
+    graph.updateSources([new AssetId.parse("app|foo.a")]);
+
+    expectNoAsset(graph, "app|foo.c");
+  });
+
+  test("doesn't find an output from the same phase", () {
+    var provider = new MockProvider(["app|foo.a"]);
+    var graph = new AssetGraph(provider, [
+      [
+        new RewriteTransformer("a", "b"),
+        new RewriteTransformer("b", "c")
+      ]
+    ]);
+    graph.updateSources([new AssetId.parse("app|foo.a")]);
+
+    expectAsset(graph, "app|foo.b", "foo.b");
+    expectNoAsset(graph, "app|foo.c");
+  });
+
+  test("finds the latest output before the transformer's phase", () {
+    var provider = new MockProvider(["app|foo.blub"]);
+    var graph = new AssetGraph(provider, [
+      [new RewriteTransformer("blub", "blub")],
+      [
+        new RewriteTransformer("blub", "blub"),
+        new RewriteTransformer("blub", "done")
+      ],
+      [new RewriteTransformer("blub", "blub")]
+    ]);
+    graph.updateSources([new AssetId.parse("app|foo.blub")]);
+
+    expectAsset(graph, "app|foo.done", "foo.blub.done");
+  });
+
+  test("applies multiple transformations to an asset", () {
+    var provider = new MockProvider(["app|foo.a"]);
+    var graph = new AssetGraph(provider, [
+      [new RewriteTransformer("a", "b")],
+      [new RewriteTransformer("b", "c")],
+      [new RewriteTransformer("c", "d")],
+      [new RewriteTransformer("d", "e")],
+      [new RewriteTransformer("e", "f")],
+      [new RewriteTransformer("f", "g")],
+      [new RewriteTransformer("g", "h")],
+      [new RewriteTransformer("h", "i")],
+      [new RewriteTransformer("i", "j")],
+      [new RewriteTransformer("j", "k")],
+    ]);
+    graph.updateSources([new AssetId.parse("app|foo.a")]);
+
+    expectAsset(graph, "app|foo.k", "foo.b.c.d.e.f.g.h.i.j.k");
+  });
+
+  test("only runs a transform once for all of its outputs", () {
+    var provider = new MockProvider(["app|foo.blub"]);
+    var transformer = new RewriteTransformer("blub", "a b c");
+    var graph = new AssetGraph(provider, [[transformer]]);
+    graph.updateSources([new AssetId.parse("app|foo.blub")]);
+
+    expectAsset(graph, "app|foo.a", "foo.a");
+    expectAsset(graph, "app|foo.b", "foo.b");
+    expectAsset(graph, "app|foo.c", "foo.c");
+    schedule(() {
+      expect(transformer.numRuns, equals(1));
+    });
+  });
+
+  test("runs transforms in the same phase in parallel", () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var transformerA = new RewriteTransformer("txt", "a");
+    var transformerB = new RewriteTransformer("txt", "b");
+    var graph = new AssetGraph(provider, [[transformerA, transformerB]]);
+
+    transformerA.wait();
+    transformerB.wait();
+
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|foo.txt")]);
+
+      // Wait for them both to start.
+      return Future.wait([transformerA.started, transformerB.started]);
+    });
+
+    schedule(() {
+      // They should both still be running.
+      expect(transformerA.isRunning, isTrue);
+      expect(transformerB.isRunning, isTrue);
+
+      transformerA.complete();
+      transformerB.complete();
+    });
+
+    expectAsset(graph, "app|foo.a", "foo.a");
+    expectAsset(graph, "app|foo.b", "foo.b");
+  });
+
+  test("does not reapply transform when inputs are not modified", () {
+    var provider = new MockProvider(["app|foo.blub"]);
+    var transformer = new RewriteTransformer("blub", "blab");
+    var graph = new AssetGraph(provider, [[transformer]]);
+    graph.updateSources([new AssetId.parse("app|foo.blub")]);
+    expectAsset(graph, "app|foo.blab", "foo.blab");
+    expectAsset(graph, "app|foo.blab", "foo.blab");
+    expectAsset(graph, "app|foo.blab", "foo.blab");
+
+    schedule(() {
+      expect(transformer.numRuns, equals(1));
+    });
+  });
+
+  test("reapplies a transform when its input is modified", () {
+    var provider = new MockProvider(["app|foo.blub"]);
+    var transformer = new RewriteTransformer("blub", "blab");
+    var graph = new AssetGraph(provider, [[transformer]]);
+
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|foo.blub")]);
+    });
+
+    expectAsset(graph, "app|foo.blab", "foo.blab");
+
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|foo.blub")]);
+    });
+
+    expectAsset(graph, "app|foo.blab", "foo.blab");
+
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|foo.blub")]);
+    });
+
+    expectAsset(graph, "app|foo.blab", "foo.blab");
+
+    schedule(() {
+      expect(transformer.numRuns, equals(3));
+    });
+  });
+
+  test("does not reapply transform when a removed input is modified", () {
+    var provider = new MockProvider({
+      "app|a.txt": "a.inc,b.inc",
+      "app|a.inc": "a",
+      "app|b.inc": "b"
+    });
+
+    var transformer = new ManyToOneTransformer("txt");
+    var graph = new AssetGraph(provider, [[transformer]]);
+
+    graph.updateSources([
+      new AssetId.parse("app|a.txt"),
+      new AssetId.parse("app|a.inc"),
+      new AssetId.parse("app|b.inc")
+    ]);
+
+    expectAsset(graph, "app|a.out", "ab");
+
+    // Remove the dependency on the non-primary input.
+    schedule(() {
+      provider.modifyAsset("app|a.txt", "a.inc");
+      graph.updateSources([new AssetId.parse("app|a.txt")]);
+    });
+
+    // Process it again.
+    expectAsset(graph, "app|a.out", "a");
+
+    // Now touch the removed input. It should not trigger another build.
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|b.inc")]);
+    });
+
+    expectAsset(graph, "app|a.out", "a");
+
+    schedule(() {
+      expect(transformer.numRuns, equals(2));
+    });
+  });
+
+  test("allows a transform to generate multiple outputs", () {
+    var provider = new MockProvider({"app|foo.txt": "a.out,b.out"});
+    var graph = new AssetGraph(provider, [
+      [new OneToManyTransformer("txt")]
+    ]);
+
+    graph.updateSources([new AssetId.parse("app|foo.txt")]);
+
+    expectAsset(graph, "app|a.out", "spread txt");
+    expectAsset(graph, "app|b.out", "spread txt");
+  });
+
+  test("does not rebuild transforms that don't use modified source", () {
+    var provider = new MockProvider(["app|foo.a", "app|foo.b"]);
+    var a = new RewriteTransformer("a", "aa");
+    var aa = new RewriteTransformer("aa", "aaa");
+    var b = new RewriteTransformer("b", "bb");
+    var bb = new RewriteTransformer("bb", "bbb");
+
+    var graph = new AssetGraph(provider, [
+      [a, b],
+      [aa, bb],
+    ]);
+
+    graph.updateSources([new AssetId.parse("app|foo.a")]);
+    graph.updateSources([new AssetId.parse("app|foo.b")]);
+
+    expectAsset(graph, "app|foo.aaa", "foo.aa.aaa");
+    expectAsset(graph, "app|foo.bbb", "foo.bb.bbb");
+
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|foo.a")]);
+    });
+
+    expectAsset(graph, "app|foo.aaa", "foo.aa.aaa");
+    expectAsset(graph, "app|foo.bbb", "foo.bb.bbb");
+
+    schedule(() {
+      expect(aa.numRuns, equals(2));
+      expect(bb.numRuns, equals(1));
+    });
+  });
+
+  test("doesn't get an output from a transform whose primary input is removed",
+      () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var graph = new AssetGraph(provider, [
+      [new RewriteTransformer("txt", "out")]
+    ]);
+
+    graph.updateSources([new AssetId.parse("app|foo.txt")]);
+
+    expectAsset(graph, "app|foo.out", "foo.out");
+
+    schedule(() {
+      graph.removeSources([new AssetId.parse("app|foo.txt")]);
+    });
+
+    expectNoAsset(graph, "app|foo.out");
+  });
+
+  test("reapplies a transform when a non-primary input changes", () {
+    var provider = new MockProvider({
+      "app|a.txt": "a.inc",
+      "app|a.inc": "a"
+    });
+
+    var graph = new AssetGraph(provider, [
+      [new ManyToOneTransformer("txt")]
+    ]);
+
+    graph.updateSources([
+      new AssetId.parse("app|a.txt"),
+      new AssetId.parse("app|a.inc")
+    ]);
+
+    expectAsset(graph, "app|a.out", "a");
+
+    schedule(() {
+      provider.modifyAsset("app|a.inc", "after");
+      graph.updateSources([new AssetId.parse("app|a.inc")]);
+    });
+
+    expectAsset(graph, "app|a.out", "after");
+  });
+
+  test("restarts processing if a change occurs during processing", () {
+    var provider = new MockProvider(["app|foo.txt"]);
+    var transformer = new RewriteTransformer("txt", "out");
+    var graph = new AssetGraph(provider, [[transformer]]);
+
+    transformer.wait();
+
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|foo.txt")]);
+
+      // Wait for the transform to start.
+      return transformer.started;
+    });
+
+    schedule(() {
+      // Now update the graph during it.
+      graph.updateSources([new AssetId.parse("app|foo.txt")]);
+    });
+
+    schedule(() {
+      transformer.complete();
+    });
+
+    expectAsset(graph, "app|foo.out", "foo.out");
+
+    schedule(() {
+      expect(transformer.numRuns, equals(2));
+    });
+  });
+
+  test("handles an output moving from one transformer to another", () {
+    // In the first run, "shared.out" is created by the "a.a" transformer.
+    var provider = new MockProvider({
+      "app|a.a": "a.out,shared.out",
+      "app|b.b": "b.out"
+    });
+
+    var graph = new AssetGraph(provider, [
+      [new OneToManyTransformer("a"), new OneToManyTransformer("b")]
+    ]);
+
+    graph.updateSources([
+      new AssetId.parse("app|a.a"),
+      new AssetId.parse("app|b.b")
+    ]);
+
+    expectAsset(graph, "app|a.out", "spread a");
+    expectAsset(graph, "app|b.out", "spread b");
+    expectAsset(graph, "app|shared.out", "spread a");
+
+    // Now switch their contents so that "shared.out" will be output by "b.b"'s
+    // transformer.
+    schedule(() {
+      provider.modifyAsset("app|a.a", "a.out");
+      provider.modifyAsset("app|b.b", "b.out,shared.out");
+      graph.updateSources([
+        new AssetId.parse("app|a.a"),
+        new AssetId.parse("app|b.b")
+      ]);
+    });
+
+    expectAsset(graph, "app|a.out", "spread a");
+    expectAsset(graph, "app|b.out", "spread b");
+    expectAsset(graph, "app|shared.out", "spread b");
+  });
+
+  test("restarts before finishing later phases when a change occurs", () {
+    var provider = new MockProvider(["app|foo.txt", "app|bar.txt"]);
+
+    var txtToInt = new RewriteTransformer("txt", "int");
+    var intToOut = new RewriteTransformer("int", "out");
+    var graph = new AssetGraph(provider, [[txtToInt], [intToOut]]);
+
+    txtToInt.wait();
+
+    schedule(() {
+      graph.updateSources([new AssetId.parse("app|foo.txt")]);
+
+      // Wait for the first transform to start.
+      return txtToInt.started;
+    });
+
+    schedule(() {
+      // Now update the graph during it.
+      graph.updateSources([new AssetId.parse("app|bar.txt")]);
+    });
+
+    schedule(() {
+      txtToInt.complete();
+    });
+
+    expectAsset(graph, "app|foo.out", "foo.int.out");
+    expectAsset(graph, "app|bar.out", "bar.int.out");
+
+    schedule(() {
+      // Should only have run each transform once for each primary.
+      expect(txtToInt.numRuns, equals(2));
+      expect(intToOut.numRuns, equals(2));
+    });
+  });
+}
diff --git a/pkg/barback/test/asset_id_test.dart b/pkg/barback/test/asset_id_test.dart
new file mode 100644
index 0000000..6834039
--- /dev/null
+++ b/pkg/barback/test/asset_id_test.dart
@@ -0,0 +1,35 @@
+// 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 barback.test.asset_id_test;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+main() {
+  initConfig();
+  group("parse", () {
+    test("parses the package and path", () {
+      var id = new AssetId.parse("package|path/to/asset.txt");
+      expect(id.package, equals("package"));
+      expect(id.path, equals("path/to/asset.txt"));
+    });
+
+    test("throws if there are multiple '|'", () {
+      expect(() => new AssetId.parse("app|path|wtf"), throwsFormatException);
+    });
+
+    test("throws if the package name is empty '|'", () {
+      expect(() => new AssetId.parse("|asset.txt"), throwsFormatException);
+    });
+
+    test("throws if the path is empty '|'", () {
+      expect(() => new AssetId.parse("app|"), throwsFormatException);
+    });
+  });
+}
diff --git a/pkg/barback/test/utils.dart b/pkg/barback/test/utils.dart
new file mode 100644
index 0000000..23f8e2a
--- /dev/null
+++ b/pkg/barback/test/utils.dart
@@ -0,0 +1,342 @@
+// 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 barback.test.utils;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+import 'package:barback/src/asset_graph.dart';
+import 'package:pathos/path.dart' as pathos;
+import 'package:scheduled_test/scheduled_test.dart';
+
+// TODO(rnystrom): Get rid of this or find a better path for it.
+import '../../../sdk/lib/_internal/pub/test/command_line_config.dart';
+
+var _configured = false;
+
+void initConfig() {
+  if (_configured) return;
+  _configured = true;
+  unittestConfiguration = new CommandLineConfiguration();
+}
+
+/// Expects that [graph] will return an asset matching [name] and [contents].
+void expectAsset(AssetGraph graph, String name, [String contents]) {
+  var id = new AssetId.parse(name);
+
+  if (contents == null) {
+    contents = pathos.basenameWithoutExtension(id.path);
+  }
+
+  schedule(() {
+    return graph.getAssetById(id).then((asset) {
+      // TODO(rnystrom): Make an actual Matcher class for this.
+      expect(asset, new isInstanceOf<MockAsset>());
+      expect(asset._id.package, equals(id.package));
+      expect(asset._id.path, equals(id.path));
+      expect(asset._contents, equals(contents));
+    });
+  }, "get asset $name");
+}
+
+/// Expects that [graph] will not find an asset matching [name].
+void expectNoAsset(AssetGraph graph, String name) {
+  var id = new AssetId.parse(name);
+
+  // Make sure the future gets the error.
+  schedule(() {
+    return graph.getAssetById(id).then((asset) {
+      fail("Should have thrown error but got $asset.");
+    }).catchError((error) {
+      expect(error, new isInstanceOf<AssetNotFoundException>());
+      expect(error.id, equals(id));
+    });
+  }, "get asset $name");
+}
+
+/// Expects that [graph] will have an output file collision error on an asset
+/// matching [name].
+Future expectCollision(AssetGraph graph, String name) {
+  var id = new AssetId.parse(name);
+  return schedule(() {
+    return graph.results.first.then((result) {
+      expect(result.error, new isInstanceOf<AssetCollisionException>());
+      expect(result.error.id, equals(id));
+    });
+  }, "get collision on $name");
+}
+
+/// Expects that [graph] will have an error on an asset matching [name] for
+/// missing [input].
+Future expectMissingInput(AssetGraph graph, String name, String input) {
+  var missing = new AssetId.parse(input);
+
+  // Make sure the future gets the error.
+  schedule(() {
+    return graph.getAssetById(new AssetId.parse(name)).then((asset) {
+      fail("Should have thrown error but got $asset.");
+    }).catchError((error) {
+      expect(error, new isInstanceOf<MissingInputException>());
+      expect(error.id, equals(missing));
+    });
+  }, "get missing input on $name");
+}
+
+/// An [AssetProvider] that provides the given set of assets.
+class MockProvider implements AssetProvider {
+  Iterable<String> get packages => _packages.keys;
+
+  final _packages = new Map<String, List<MockAsset>>();
+
+  /// The completer that [getAsset()] is waiting on to complete.
+  ///
+  /// If `null` it will return the asset immediately.
+  Completer _wait;
+
+  /// Tells the provider to wait during [getAsset] until [complete()]
+  /// is called.
+  ///
+  /// Lets you test the asynchronous behavior of loading.
+  void wait() {
+    _wait = new Completer();
+  }
+
+  void complete() {
+    _wait.complete();
+    _wait = null;
+  }
+
+  MockProvider(assets) {
+    if (assets is Map) {
+      assets.forEach((asset, contents) {
+        var id = new AssetId.parse(asset);
+        var package = _packages.putIfAbsent(id.package, () => []);
+        package.add(new MockAsset(id, contents));
+      });
+    } else if (assets is Iterable) {
+      for (var asset in assets) {
+        var id = new AssetId.parse(asset);
+        var package = _packages.putIfAbsent(id.package, () => []);
+        var contents = pathos.basenameWithoutExtension(id.path);
+        package.add(new MockAsset(id, contents));
+      }
+    }
+  }
+
+  void modifyAsset(String name, String contents) {
+    var id = new AssetId.parse(name);
+    var asset = _packages[id.package].firstWhere((a) => a._id == id);
+    asset._contents = contents;
+  }
+
+  List<AssetId> listAssets(String package, {String within}) {
+    if (within != null) {
+      throw new UnimplementedError("Doesn't handle 'within' yet.");
+    }
+
+    return _packages[package].map((asset) => asset.id);
+  }
+
+  Future<Asset> getAsset(AssetId id) {
+    var future;
+    if (_wait != null) {
+      future = _wait.future;
+    } else {
+      future = new Future.value();
+    }
+
+    return future.then((_) {
+      var package = _packages[id.package];
+      if (package == null) throw new AssetNotFoundException(id);
+
+      return package.firstWhere((asset) => asset._id == id,
+          orElse: () => throw new AssetNotFoundException(id));
+    });
+  }
+}
+
+/// A [Transformer] that takes assets ending with one extension and generates
+/// assets with a given extension.
+///
+/// Appends the output extension to the contents of the input file.
+class RewriteTransformer extends Transformer {
+  final String from;
+  final String to;
+
+  /// The number of times the transformer has been applied.
+  int numRuns = 0;
+
+  /// The number of currently running transforms.
+  int _runningTransforms = 0;
+
+  /// The completer that the transform is waiting on to complete.
+  ///
+  /// If `null` the transform will complete immediately.
+  Completer _wait;
+
+  /// A future that completes when the first apply of this transformer begins.
+  Future get started => _started.future;
+  final _started = new Completer();
+
+  /// Creates a transformer that rewrites assets whose extension is [from] to
+  /// one whose extension is [to].
+  ///
+  /// [to] may be a space-separated list in which case multiple outputs will be
+  /// created for each input.
+  RewriteTransformer(this.from, this.to);
+
+  /// `true` if any transforms are currently running.
+  bool get isRunning => _runningTransforms > 0;
+
+  /// Tells the transform to wait during its transformation until [complete()]
+  /// is called.
+  ///
+  /// Lets you test the asynchronous behavior of transformers.
+  void wait() {
+    _wait = new Completer();
+  }
+
+  void complete() {
+    _wait.complete();
+    _wait = null;
+  }
+
+  Future<bool> isPrimary(AssetId asset) {
+    return new Future.value(asset.extension == ".$from");
+  }
+
+  Future apply(Transform transform) {
+    numRuns++;
+    if (!_started.isCompleted) _started.complete();
+    _runningTransforms++;
+    return transform.primaryInput.then((input) {
+      for (var extension in to.split(" ")) {
+        var id = transform.primaryId.changeExtension(".$extension");
+        var content = input.readAsString() + ".$extension";
+        transform.addOutput(id, new MockAsset(id, content));
+
+      }
+
+      if (_wait != null) return _wait.future;
+    }).whenComplete(() {
+      _runningTransforms--;
+    });
+  }
+
+  String toString() => "$from->$to";
+}
+
+/// A [Transformer] that takes an input asset that contains a comma-separated
+/// list of paths and outputs a file for each path.
+class OneToManyTransformer extends Transformer {
+  final String extension;
+
+  /// The number of times the transformer has been applied.
+  int numRuns = 0;
+
+  /// Creates a transformer that consumes assets with [extension].
+  ///
+  /// That file contains a comma-separated list of paths and it will output
+  /// files at each of those paths.
+  OneToManyTransformer(this.extension);
+
+  Future<bool> isPrimary(AssetId asset) {
+    return new Future.value(asset.extension == ".$extension");
+  }
+
+  Future apply(Transform transform) {
+    numRuns++;
+    return transform.primaryInput.then((input) {
+      for (var line in input.readAsString().split(",")) {
+        var id = new AssetId(transform.primaryId.package, line);
+        transform.addOutput(id, new MockAsset(id, "spread $extension"));
+      }
+    });
+  }
+
+  String toString() => "1->many $extension";
+}
+
+/// A transformer that uses the contents of a file to define the other inputs.
+///
+/// Outputs a file with the same name as the primary but with an "out"
+/// extension containing the concatenated contents of all non-primary inputs.
+class ManyToOneTransformer extends Transformer {
+  final String extension;
+
+  /// The number of times the transformer has been applied.
+  int numRuns = 0;
+
+  /// Creates a transformer that consumes assets with [extension].
+  ///
+  /// That file contains a comma-separated list of paths and it will input
+  /// files at each of those paths.
+  ManyToOneTransformer(this.extension);
+
+  Future<bool> isPrimary(AssetId asset) {
+    return new Future.value(asset.extension == ".$extension");
+  }
+
+  Future apply(Transform transform) {
+    numRuns++;
+    return transform.primaryInput.then((primary) {
+      // Get all of the included inputs.
+      var inputs = primary.readAsString().split(",").map((path) {
+        var id = new AssetId(transform.primaryId.package, path);
+        return transform.getInput(id);
+      });
+
+      // Concatenate them to one output.
+      return Future.wait(inputs).then((inputs) {
+        var id = transform.primaryId.changeExtension(".out");
+        var contents = inputs.map((input) => input.readAsString()).join();
+        transform.addOutput(id, new MockAsset(id, contents));
+      });
+    });
+  }
+
+  String toString() => "many->1 $extension";
+}
+
+/// A transformer that throws an exception when run, after generating the
+/// given outputs.
+class BadTransformer extends Transformer {
+  /// The error it throws.
+  static const ERROR = "I am a bad transformer!";
+
+  /// The list of asset names that it should output.
+  final List<String> outputs;
+
+  BadTransformer(this.outputs);
+
+  Future<bool> isPrimary(AssetId asset) => new Future.value(true);
+  Future apply(Transform transform) {
+    return new Future(() {
+      // Create the outputs first.
+      for (var output in outputs) {
+        var id = new AssetId.parse(output);
+        transform.addOutput(id, new MockAsset(id, output));
+      }
+
+      // Then fail.
+      throw ERROR;
+    });
+  }
+}
+
+/// An implementation of [Asset] that never hits the file system.
+class MockAsset implements Asset {
+  final AssetId _id;
+  String _contents;
+
+  MockAsset(this._id, this._contents);
+
+  String readAsString() => _contents;
+  Stream<List<int>> read() => throw new UnimplementedError();
+
+  serialize() => throw new UnimplementedError();
+
+  String toString() => "MockAsset $_id $_contents";
+}
\ No newline at end of file
diff --git a/pkg/docgen/bin/docgen.dart b/pkg/docgen/bin/docgen.dart
index 308df28..6222b0f 100644
--- a/pkg/docgen/bin/docgen.dart
+++ b/pkg/docgen/bin/docgen.dart
@@ -2,392 +2,56 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * The docgen tool takes in a library as input and produces documentation
- * for the library as well as all libraries it imports and uses. The tool can
- * be run by passing in the path to a .dart file like this:
- *
- *   ./dart docgen.dart path/to/file.dart
- *
- * This outputs information about all classes, variables, functions, and
- * methods defined in the library and its imported libraries.
- */
-library docgen;
-
-// TODO(tmandel): Use 'package:' references for imports with relative paths.
 import 'dart:io';
-import 'dart:json';
-import 'dart:async';
-import '../lib/dart2yaml.dart';
-import '../lib/src/dart2js_mirrors.dart';
-import 'package:markdown/markdown.dart' as markdown;
-import '../../args/lib/args.dart';
-import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart';
-import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart';
+
+import 'package:args/args.dart';
+import 'package:logging/logging.dart';
+
+import '../lib/docgen.dart';
 
 /**
- * Entry function to create YAML documentation from Dart files.
+ * Analyzes Dart files and generates a representation of included libraries, 
+ * classes, and members. 
  */
 void main() {
-  // TODO(tmandel): Use args library once flags are clear.
-  Options opts = new Options();
-  Docgen docgen = new Docgen();
-  
-  if (opts.arguments.length > 0) {
-    List<Path> libraries = [new Path(opts.arguments[0])];
-    Path sdkDirectory = new Path("../../../sdk/");
-    var workingMirrors = analyze(libraries, sdkDirectory, 
-        options: ['--preserve-comments', '--categories=Client,Server']);
-    workingMirrors.then( (MirrorSystem mirrorSystem) {
-      var mirrors = mirrorSystem.libraries.values;
-      if (mirrors.isEmpty) {
-        print("no LibraryMirrors");
-      } else {
-        docgen.libraries = mirrors;
-        docgen.documentLibraries();
-      }
-    });
-  }
+  logger.onRecord.listen((record) => print(record.message));
+  var results = initArgParser().parse(new Options().arguments);
+  if (results['help']) return;  
+  new Docgen(results);
 }
 
 /**
- * This class documents a list of libraries.
+ * Creates parser for docgen command line arguments. 
  */
-class Docgen {
-
-  /// Libraries to be documented.
-  List<LibraryMirror> _libraries;
+ArgParser initArgParser() {
+  var parser = new ArgParser();
+  parser.addFlag('help', abbr: 'h', 
+      help: 'Prints help and usage information.', 
+      negatable: false, 
+      callback: (help) {
+        if (help) {
+          logger.info(parser.getUsage());
+          logger.info(usage);
+        }
+      });
+  parser.addFlag('verbose', abbr: 'v', 
+      help: 'Output more logging information.', negatable: false, 
+      callback: (verbose) {
+        if (verbose) Logger.root.level = Level.FINEST;
+      });
+  parser.addOption('output-format', abbr: 'o', 
+      help: 'Sets the output format.', 
+      allowed: ['yaml', 'json'], 
+      allowedHelp: {'yaml' : 'Outputs to YAML. (Default)', 
+        'json' : 'Outputs to JSON.'});
+  parser.addFlag('yaml', abbr: 'y', 
+      help: 'Same as output-format=yaml.', negatable: false);
+  parser.addFlag('json', abbr: 'j', 
+      help: 'Same as output-format=json.', negatable: false);
+  parser.addFlag('include-private', 
+      help: 'Flag to include private declarations.', negatable: false);
+  parser.addFlag('include-sdk', 
+      help: 'Flag to parse SDK Library files.', negatable: false);
   
-  /// Saves list of libraries for Docgen object.
-  void set libraries(value) => _libraries = value;
-  
-  /// Current library being documented to be used for comment links.
-  LibraryMirror _currentLibrary;
-  
-  /// Current class being documented to be used for comment links.
-  ClassMirror _currentClass;
-  
-  /// Current member being documented to be used for comment links.
-  MemberMirror _currentMember;
-  
-  /// Should the output file type be JSON?
-  // TODO(tmandel): Add flag to allow for output to JSON.
-  bool outputToJson = false;
-  
-  /// Resolves reference links
-  markdown.Resolver linkResolver;
-  
-  /**
-   * Docgen constructor initializes the link resolver for markdown parsing.
-   */
-  Docgen() {
-    this.linkResolver = (name) => 
-        fixReference(name, _currentLibrary, _currentClass, _currentMember);
-  }
-  
-  /**
-   * Creates documentation for filtered libraries.
-   */
-  void documentLibraries() {
-    //TODO(tmandel): Filter libraries and determine output type using flags.
-    _libraries.forEach((library) {
-      _currentLibrary = library;
-      var result = new Library(library.qualifiedName, _getComment(library),
-          _getVariables(library.variables), _getMethods(library.functions),
-          _getClasses(library.classes));
-      if (outputToJson) {
-        _writeToFile(stringify(result.toMap()), "${result.name}.json");
-      } else {
-        _writeToFile(getYamlString(result.toMap()), "${result.name}.yaml");
-      }
-    });
-   }
-  
-  /**
-   * Returns any documentation comments associated with a mirror with
-   * simple markdown converted to html.
-   */
-  String _getComment(DeclarationMirror mirror) {
-    String commentText;
-    mirror.metadata.forEach((metadata) {
-      if (metadata is CommentInstanceMirror) {
-        CommentInstanceMirror comment = metadata;
-        if (comment.isDocComment) {
-          if (commentText == null) {
-            commentText = comment.trimmedText;
-          } else {
-            commentText = "$commentText ${comment.trimmedText}";
-          }
-        } 
-      }
-    });
-    return commentText == null ? "" : 
-      markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver);
-  }
-
-  /**
-   * Converts all [_] references in comments to <code>_</code>.
-   */
-  // TODO(tmandel): Create proper links for [_] style markdown based
-  // on scope once layout of viewer is finished.
-  markdown.Node fixReference(String name, LibraryMirror currentLibrary, 
-      ClassMirror currentClass, MemberMirror currentMember) {
-    return new markdown.Element.text('code', name);
-  }
-  
-  /**
-   * Returns a map of [Variable] objects constructed from inputted mirrors.
-   */
-  Map<String, Variable> _getVariables(Map<String, VariableMirror> mirrorMap) {
-    var data = {};
-    mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
-      _currentMember = mirror;
-      data[mirrorName] = new Variable(mirrorName, mirror.isFinal,
-          mirror.isStatic, mirror.type.toString(), _getComment(mirror));
-    });
-    return data;
-  }
-  
-  /**
-   * Returns a map of [Method] objects constructed from inputted mirrors.
-   */
-  Map<String, Method> _getMethods(Map<String, MethodMirror> mirrorMap) {
-    var data = {};
-    mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
-      _currentMember = mirror;
-      data[mirrorName] = new Method(mirrorName, mirror.isSetter,
-          mirror.isGetter, mirror.isConstructor, mirror.isOperator, 
-          mirror.isStatic, mirror.returnType.toString(), _getComment(mirror),
-          _getParameters(mirror.parameters));
-    });
-    return data;
-  } 
-  
-  /**
-   * Returns a map of [Class] objects constructed from inputted mirrors.
-   */
-  Map<String, Class> _getClasses(Map<String, ClassMirror> mirrorMap) {
-    var data = {};
-    mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
-      _currentClass = mirror;
-      var superclass;
-      if (mirror.superclass != null) {
-        superclass = mirror.superclass.qualifiedName;
-      }
-      var interfaces = 
-          mirror.superinterfaces.map((interface) => interface.qualifiedName);
-      data[mirrorName] = new Class(mirrorName, superclass, mirror.isAbstract,
-          mirror.isTypedef, _getComment(mirror), interfaces,
-          _getVariables(mirror.variables), _getMethods(mirror.methods));
-    });
-    return data;
-  }
-  
-  /**
-   * Returns a map of [Parameter] objects constructed from inputted mirrors.
-   */
-  Map<String, Parameter> _getParameters(List<ParameterMirror> mirrorList) {
-    var data = {};
-    mirrorList.forEach((ParameterMirror mirror) {
-      _currentMember = mirror;
-      data[mirror.simpleName] = new Parameter(mirror.simpleName, 
-          mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, 
-          mirror.type.toString(), mirror.defaultValue);
-    });
-    return data;
-  }
+  return parser;
 }
-
-/**
- * Transforms the map by calling toMap on each value in it.
- */
-Map recurseMap(Map inputMap) {
-  var outputMap = {};
-  inputMap.forEach((key, value) {
-    outputMap[key] = value.toMap();
-  });
-  return outputMap;
-}
-
-/**
- * A class containing contents of a Dart library.
- */
-class Library {
-  
-  /// Documentation comment with converted markdown.
-  String comment;
-  
-  /// Top-level variables in the library.
-  Map<String, Variable> variables;
-  
-  /// Top-level functions in the library.
-  Map<String, Method> functions;
-  
-  /// Classes defined within the library
-  Map<String, Class> classes;
-  
-  String name;
-  
-  Library(this.name, this.comment, this.variables, 
-      this.functions, this.classes);
-  
-  /// Generates a map describing the [Library] object.
-  Map toMap() {
-    var libraryMap = {};
-    libraryMap["name"] = name;
-    libraryMap["comment"] = comment;
-    libraryMap["variables"] = recurseMap(variables);
-    libraryMap["functions"] = recurseMap(functions);
-    libraryMap["classes"] = recurseMap(classes);
-    return libraryMap;
-  }
-}
-
-/**
- * A class containing contents of a Dart class.
- */
-// TODO(tmandel): Figure out how to do typedefs (what is needed)
-class Class {
-  
-  /// Documentation comment with converted markdown.
-  String comment;
-  
-  /// List of the names of interfaces that this class implements.
-  List<String> interfaces;
-  
-  /// Top-level variables in the class.
-  Map<String, Variable> variables;
-  
-  /// Methods in the class.
-  Map<String, Method> methods;
-  
-  String name;
-  String superclass;
-  bool isAbstract;
-  bool isTypedef;
- 
-  Class(this.name, this.superclass, this.isAbstract, this.isTypedef,
-      this.comment, this.interfaces, this.variables, this.methods); 
-  
-  /// Generates a map describing the [Class] object.
-  Map toMap() {
-    var classMap = {};
-    classMap["name"] = name;
-    classMap["comment"] = comment;
-    classMap["superclass"] = superclass;
-    classMap["abstract"] = isAbstract.toString();
-    classMap["typedef"] = isTypedef.toString();
-    classMap["implements"] = new List.from(interfaces);
-    classMap["variables"] = recurseMap(variables);
-    classMap["methods"] = recurseMap(methods);
-    return classMap;
-  }
-}
-
-/**
- * A class containing properties of a Dart variable.
- */
-class Variable {
-  
-  /// Documentation comment with converted markdown.
-  String comment;
-  
-  String name;
-  bool isFinal;
-  bool isStatic;
-  String type;
-  
-  Variable(this.name, this.isFinal, this.isStatic, this.type, this.comment);
-  
-  /// Generates a map describing the [Variable] object.
-  Map toMap() {
-    var variableMap = {};
-    variableMap["name"] = name;
-    variableMap["comment"] = comment;
-    variableMap["final"] = isFinal.toString();
-    variableMap["static"] = isStatic.toString();
-    variableMap["type"] = type;
-    return variableMap;
-  }
-}
-
-/**
- * A class containing properties of a Dart method.
- */
-class Method {
-  
-  /// Documentation comment with converted markdown.
-  String comment;
-  
-  /// Parameters for this method.
-  Map<String, Parameter> parameters;
-  
-  String name;
-  bool isSetter;
-  bool isGetter;
-  bool isConstructor;
-  bool isOperator;
-  bool isStatic;
-  String returnType;
-  
-  Method(this.name, this.isSetter, this.isGetter, this.isConstructor,
-      this.isOperator, this.isStatic, this.returnType, this.comment,
-      this.parameters);
-  
-  /// Generates a map describing the [Method] object.
-  Map toMap() {
-    var methodMap = {};
-    methodMap["name"] = name;
-    methodMap["comment"] = comment;
-    methodMap["type"] = isSetter ? "setter" : isGetter ? "getter" :
-      isOperator ? "operator" : isConstructor ? "constructor" : "method";
-    methodMap["static"] = isStatic.toString();
-    methodMap["return"] = returnType;
-    methodMap["parameters"] = recurseMap(parameters);
-    return methodMap;
-  }  
-}
-
-/**
- * A class containing properties of a Dart method/function parameter.
- */
-class Parameter {
-  
-  String name;
-  bool isOptional;
-  bool isNamed;
-  bool hasDefaultValue;
-  String type;
-  String defaultValue;
-  
-  Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue,
-      this.type, this.defaultValue);
-  
-  /// Generates a map describing the [Parameter] object.
-  Map toMap() {
-    var parameterMap = {};
-    parameterMap["name"] = name;
-    parameterMap["optional"] = isOptional.toString();
-    parameterMap["named"] = isNamed.toString();
-    parameterMap["default"] = hasDefaultValue.toString();
-    parameterMap["type"] = type;
-    parameterMap["value"] = defaultValue;
-    return parameterMap;
-  } 
-}
-
-/**
- * Writes text to a file in the 'docs' directory.
- */
-void _writeToFile(String text, String filename) {
-  Directory dir = new Directory('docs');
-  if (!dir.existsSync()) {
-    dir.createSync();
-  }
-  File file = new File('docs/$filename');
-  if (!file.exists()) {
-    file.createSync();
-  }
-  file.openSync();
-  file.writeAsString(text);
-}
\ No newline at end of file
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
new file mode 100644
index 0000000..52d10d2
--- /dev/null
+++ b/pkg/docgen/lib/docgen.dart
@@ -0,0 +1,508 @@
+// 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.
+
+/**
+ * **docgen** is a tool for creating machine readable representations of Dart 
+ * code metadata, including: classes, members, comments and annotations.
+ * 
+ * docgen is run on a `.dart` file or a directory containing `.dart` files. 
+ * 
+ *      $ dart docgen.dart [OPTIONS] [FILE/DIR]
+ *
+ * This creates files called `docs/<library_name>.yaml` in your current 
+ * working directory.
+ */
+library docgen;
+
+import 'dart:io';
+import 'dart:json';
+import 'dart:async';
+
+import 'package:args/args.dart';
+import 'package:logging/logging.dart';
+import 'package:markdown/markdown.dart' as markdown;
+import 'package:pathos/path.dart' as path;
+
+import 'dart2yaml.dart';
+import 'src/io.dart';
+import '../../../sdk/lib/_internal/compiler/compiler.dart' as api;
+import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart'
+    as dart2js;
+import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider.dart';
+
+var logger = new Logger('Docgen');
+
+const String usage = 'Usage: dart docgen.dart [OPTIONS] [fooDir/barFile]';
+
+/**
+ * This class documents a list of libraries.
+ */
+class Docgen {
+
+  /// Libraries to be documented.
+  List<LibraryMirror> _libraries;
+
+  /// Current library being documented to be used for comment links.
+  LibraryMirror _currentLibrary;
+  
+  /// Current class being documented to be used for comment links.
+  ClassMirror _currentClass;
+  
+  /// Current member being documented to be used for comment links.
+  MemberMirror _currentMember;
+  
+  /// Resolves reference links in doc comments. 
+  markdown.Resolver linkResolver;
+  
+  /// Package directory of directory being analyzed. 
+  String packageDir;
+  
+  bool outputToYaml;
+  bool outputToJson;
+  bool includePrivate;
+  /// State for whether or not the SDK libraries should also be outputted.
+  bool includeSdk;
+
+  /**
+   * Docgen constructor initializes the link resolver for markdown parsing.
+   * Also initializes the command line arguments. 
+   */
+  Docgen(ArgResults argResults) {  
+    if (argResults['output-format'] == null) {
+      outputToYaml = 
+          (argResults['yaml'] == false && argResults['json'] == false) ?
+              true : argResults['yaml'];
+    } else {
+      if ((argResults['output-format'] == 'yaml' && 
+          argResults['json'] == true) || 
+          (argResults['output-format'] == 'json' && 
+          argResults['yaml'] == true)) {
+        throw new UnsupportedError('Cannot have contradictory output flags.');
+      }
+      outputToYaml = argResults['output-format'] == 'yaml' ? true : false;
+    }
+    outputToJson = !outputToYaml;
+    includePrivate = argResults['include-private'];
+    includeSdk = argResults['include-sdk'];
+    
+    this.linkResolver = (name) => 
+        fixReference(name, _currentLibrary, _currentClass, _currentMember);
+    
+    analyze(argResults.rest);
+  }
+  
+  List<String> listLibraries(List<String> args) {
+    // TODO(janicejl): At the moment, only have support to have either one file,
+    // or one directory. This is because there can only be one package directory
+    // since only one docgen is created per run. 
+    if (args.length != 1) throw new UnsupportedError(usage);
+    var libraries = new List<String>();
+    var type = FileSystemEntity.typeSync(args[0]);
+    
+    if (type == FileSystemEntityType.FILE) {
+      libraries.add(path.absolute(args[0]));
+      logger.info('Added to libraries: ${libraries.last}');
+    } else {
+      libraries.addAll(listDartFromDir(args[0]));
+    } 
+    logger.info('Package Directory: $packageDir');
+    return libraries;
+  }
+
+  List<String> listDartFromDir(String args) {
+    var files = listDir(args, recursive: true);
+    packageDir = files.firstWhere((f) => 
+        f.endsWith('/pubspec.yaml'), orElse: () => '');
+    if (packageDir != '') packageDir = path.dirname(packageDir) + '/packages';
+    return files.where((f) => 
+        f.endsWith('.dart') && !f.contains('/packages')).toList()
+        ..forEach((lib) => logger.info('Added to libraries: $lib'));
+  }
+
+  /**
+   * Analyzes set of libraries by getting a mirror system and triggers the 
+   * documentation of the libraries. 
+   */
+  void analyze(List<String> args) {
+    var libraries = listLibraries(args);
+    if (libraries.isEmpty) throw new StateError('No Libraries.');
+    // DART_SDK should be set to the root of the SDK library. 
+    var sdkRoot = Platform.environment['DART_SDK'];
+    if (sdkRoot != null) {
+      logger.info('Using DART_SDK to find SDK at $sdkRoot');
+    } else {
+      // If DART_SDK is not defined in the environment, 
+      // assuming the dart executable is from the Dart SDK folder inside bin. 
+      sdkRoot = path.dirname(path.dirname(new Options().executable));
+      logger.info('SDK Root: ${sdkRoot}');
+    }
+    
+    getMirrorSystem(libraries, sdkRoot, packageRoot: packageDir)
+        .then((MirrorSystem mirrorSystem) {
+          if (mirrorSystem.libraries.values.isEmpty) {
+            throw new UnsupportedError('No Library Mirrors.');
+          } 
+          this.libraries = mirrorSystem.libraries.values;
+          documentLibraries();
+        });
+  }
+  
+  /**
+   * Analyzes set of libraries and provides a mirror system which can be used 
+   * for static inspection of the source code.
+   */
+  Future<MirrorSystem> getMirrorSystem(List<String> libraries,
+        String libraryRoot, {String packageRoot}) {
+    SourceFileProvider provider = new SourceFileProvider();
+    api.DiagnosticHandler diagnosticHandler =
+          new FormattingDiagnosticHandler(provider).diagnosticHandler;
+    Uri libraryUri = currentDirectory.resolve(appendSlash('$libraryRoot'));
+    Uri packageUri = null;
+    if (packageRoot != null) {
+      packageUri = currentDirectory.resolve(appendSlash('$packageRoot'));
+    }
+    List<Uri> librariesUri = <Uri>[];
+    libraries.forEach((library) {
+      librariesUri.add(currentDirectory.resolve(library));
+    });
+    return dart2js.analyze(librariesUri, libraryUri, packageUri,
+        provider.readStringFromUri, diagnosticHandler,
+        ['--preserve-comments', '--categories=Client,Server']);
+  }
+  
+  /**
+   * Creates documentation for filtered libraries.
+   */
+  void documentLibraries() {
+    _libraries.forEach((library) {
+      // Files belonging to the SDK have a uri that begins with 'dart:'.
+      if (includeSdk || !library.uri.toString().startsWith('dart:')) {
+        _currentLibrary = library;
+        var result = new Library(library.qualifiedName, _getComment(library),
+            _getVariables(library.variables), _getMethods(library.functions),
+            _getClasses(library.classes));
+        if (outputToJson) {
+          _writeToFile(stringify(result.toMap()), '${result.name}.json');
+        } 
+        if (outputToYaml) {
+          _writeToFile(getYamlString(result.toMap()), '${result.name}.yaml');
+        }
+     }
+    });
+   }
+
+  /// Saves list of libraries for Docgen object.
+  void set libraries(value){
+    _libraries = value;
+  }
+  
+  /**
+   * Returns any documentation comments associated with a mirror with
+   * simple markdown converted to html.
+   */
+  String _getComment(DeclarationMirror mirror) {
+    String commentText;
+    mirror.metadata.forEach((metadata) {
+      if (metadata is CommentInstanceMirror) {
+        CommentInstanceMirror comment = metadata;
+        if (comment.isDocComment) {
+          if (commentText == null) {
+            commentText = comment.trimmedText;
+          } else {
+            commentText = '$commentText ${comment.trimmedText}';
+          }
+        } 
+      }
+    });
+    commentText = commentText == null ? '' : 
+        markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver)
+        .replaceAll('\n', '');
+    return commentText;
+  }
+
+  /**
+   * Converts all [_] references in comments to <code>_</code>.
+   */
+  // TODO(tmandel): Create proper links for [_] style markdown based
+  // on scope once layout of viewer is finished.
+  markdown.Node fixReference(String name, LibraryMirror currentLibrary, 
+      ClassMirror currentClass, MemberMirror currentMember) {
+    return new markdown.Element.text('code', name);
+  }
+  
+  /**
+   * Returns a map of [Variable] objects constructed from inputted mirrors.
+   */
+  Map<String, Variable> _getVariables(Map<String, VariableMirror> mirrorMap) {
+    var data = {};
+    mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
+      if (includePrivate || !mirror.isPrivate) {
+        _currentMember = mirror;
+        data[mirrorName] = new Variable(mirrorName, mirror.qualifiedName, 
+            mirror.isFinal, mirror.isStatic, mirror.type.qualifiedName, 
+            _getComment(mirror));
+      }
+    });
+    return data;
+  }
+  
+  /**
+   * Returns a map of [Method] objects constructed from inputted mirrors.
+   */
+  Map<String, Method> _getMethods(Map<String, MethodMirror> mirrorMap) {
+    var data = {};
+    mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
+      if (includePrivate || !mirror.isPrivate) {
+        _currentMember = mirror;
+        data[mirrorName] = new Method(mirrorName, mirror.qualifiedName, 
+            mirror.isSetter, mirror.isGetter, mirror.isConstructor, 
+            mirror.isOperator, mirror.isStatic, mirror.returnType.qualifiedName, 
+            _getComment(mirror), _getParameters(mirror.parameters));
+      }
+    });
+    return data;
+  } 
+  
+  /**
+   * Returns a map of [Class] objects constructed from inputted mirrors.
+   */
+  Map<String, Class> _getClasses(Map<String, ClassMirror> mirrorMap) {
+    var data = {};
+    mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
+      if (includePrivate || !mirror.isPrivate) {
+        _currentClass = mirror;
+        var superclass = (mirror.superclass != null) ? 
+            mirror.superclass.qualifiedName : '';
+        var interfaces = 
+            mirror.superinterfaces.map((interface) => interface.qualifiedName);
+        data[mirrorName] = new Class(mirrorName, mirror.qualifiedName, 
+            superclass, mirror.isAbstract, mirror.isTypedef, 
+            _getComment(mirror), interfaces.toList(),
+            _getVariables(mirror.variables), _getMethods(mirror.methods));
+      }
+    });
+    return data;
+  }
+  
+  /**
+   * Returns a map of [Parameter] objects constructed from inputted mirrors.
+   */
+  Map<String, Parameter> _getParameters(List<ParameterMirror> mirrorList) {
+    var data = {};
+    mirrorList.forEach((ParameterMirror mirror) {
+      _currentMember = mirror;
+      data[mirror.simpleName] = new Parameter(mirror.simpleName, 
+          mirror.qualifiedName, mirror.isOptional, mirror.isNamed, 
+          mirror.hasDefaultValue, mirror.type.qualifiedName, 
+          mirror.defaultValue);
+    });
+    return data;
+  }
+}
+
+/**
+ * Transforms the map by calling toMap on each value in it.
+ */
+Map recurseMap(Map inputMap) {
+  var outputMap = {};
+  inputMap.forEach((key, value) {
+    outputMap[key] = value.toMap();
+  });
+  return outputMap;
+}
+
+/**
+ * A class containing contents of a Dart library.
+ */
+class Library {
+  
+  /// Documentation comment with converted markdown.
+  String comment;
+  
+  /// Top-level variables in the library.
+  Map<String, Variable> variables;
+  
+  /// Top-level functions in the library.
+  Map<String, Method> functions;
+  
+  /// Classes defined within the library
+  Map<String, Class> classes;
+  
+  String name;
+  
+  Library(this.name, this.comment, this.variables, 
+      this.functions, this.classes);
+  
+  /// Generates a map describing the [Library] object.
+  Map toMap() {
+    var libraryMap = {};
+    libraryMap['name'] = name;
+    libraryMap['comment'] = comment;
+    libraryMap['variables'] = recurseMap(variables);
+    libraryMap['functions'] = recurseMap(functions);
+    libraryMap['classes'] = recurseMap(classes);
+    return libraryMap;
+  }
+}
+
+/**
+ * A class containing contents of a Dart class.
+ */
+// TODO(tmandel): Figure out how to do typedefs (what is needed)
+class Class {
+  
+  /// Documentation comment with converted markdown.
+  String comment;
+  
+  /// List of the names of interfaces that this class implements.
+  List<String> interfaces;
+  
+  /// Top-level variables in the class.
+  Map<String, Variable> variables;
+  
+  /// Methods in the class.
+  Map<String, Method> methods;
+  
+  String name;
+  String qualifiedName;
+  String superclass;
+  bool isAbstract;
+  bool isTypedef;
+ 
+  Class(this.name, this.qualifiedName, this.superclass, this.isAbstract, this.isTypedef,
+      this.comment, this.interfaces, this.variables, this.methods);
+  
+  /// Generates a map describing the [Class] object.
+  Map toMap() {
+    var classMap = {};
+    classMap['name'] = name;
+    classMap['qualifiedname'] = qualifiedName;
+    classMap['comment'] = comment;
+    classMap['superclass'] = superclass;
+    classMap['abstract'] = isAbstract.toString();
+    classMap['typedef'] = isTypedef.toString();
+    classMap['implements'] = new List.from(interfaces);
+    classMap['variables'] = recurseMap(variables);
+    classMap['methods'] = recurseMap(methods);
+    return classMap;
+  }
+}
+
+/**
+ * A class containing properties of a Dart variable.
+ */
+class Variable {
+  
+  /// Documentation comment with converted markdown.
+  String comment;
+  
+  String name;
+  String qualifiedName;
+  bool isFinal;
+  bool isStatic;
+  String type;
+  
+  Variable(this.name, this.qualifiedName, this.isFinal, this.isStatic, 
+      this.type, this.comment);
+  
+  /// Generates a map describing the [Variable] object.
+  Map toMap() {
+    var variableMap = {};
+    variableMap['name'] = name;
+    variableMap['qualifiedname'] = qualifiedName;
+    variableMap['comment'] = comment;
+    variableMap['final'] = isFinal.toString();
+    variableMap['static'] = isStatic.toString();
+    variableMap['type'] = type;
+    return variableMap;
+  }
+}
+
+/**
+ * A class containing properties of a Dart method.
+ */
+class Method {
+  
+  /// Documentation comment with converted markdown.
+  String comment;
+  
+  /// Parameters for this method.
+  Map<String, Parameter> parameters;
+  
+  String name;
+  String qualifiedName;
+  bool isSetter;
+  bool isGetter;
+  bool isConstructor;
+  bool isOperator;
+  bool isStatic;
+  String returnType;
+  
+  Method(this.name, this.qualifiedName, this.isSetter, this.isGetter, 
+      this.isConstructor, this.isOperator, this.isStatic, this.returnType, 
+      this.comment, this.parameters);
+  
+  /// Generates a map describing the [Method] object.
+  Map toMap() {
+    var methodMap = {};
+    methodMap['name'] = name;
+    methodMap['qualifiedname'] = qualifiedName;
+    methodMap['comment'] = comment;
+    methodMap['type'] = isSetter ? 'setter' : isGetter ? 'getter' :
+      isOperator ? 'operator' : isConstructor ? 'constructor' : 'method';
+    methodMap['static'] = isStatic.toString();
+    methodMap['return'] = returnType;
+    methodMap['parameters'] = recurseMap(parameters);
+    return methodMap;
+  }  
+}
+
+/**
+ * A class containing properties of a Dart method/function parameter.
+ */
+class Parameter {
+  
+  String name;
+  String qualifiedName;
+  bool isOptional;
+  bool isNamed;
+  bool hasDefaultValue;
+  String type;
+  String defaultValue;
+  
+  Parameter(this.name, this.qualifiedName, this.isOptional, this.isNamed, this.hasDefaultValue,
+      this.type, this.defaultValue);
+  
+  /// Generates a map describing the [Parameter] object.
+  Map toMap() {
+    var parameterMap = {};
+    parameterMap['name'] = name;
+    parameterMap['qualifiedname'] = qualifiedName;
+    parameterMap['optional'] = isOptional.toString();
+    parameterMap['named'] = isNamed.toString();
+    parameterMap['default'] = hasDefaultValue.toString();
+    parameterMap['type'] = type;
+    parameterMap['value'] = defaultValue;
+    return parameterMap;
+  } 
+}
+
+/**
+ * Writes text to a file in the 'docs' directory.
+ */
+void _writeToFile(String text, String filename) {
+  Directory dir = new Directory('docs');
+  if (!dir.existsSync()) {
+    dir.createSync();
+  }
+  File file = new File('docs/$filename');
+  if (!file.existsSync()) {
+    file.createSync();
+  }
+  file.openSync();
+  file.writeAsString(text);
+}
\ No newline at end of file
diff --git a/pkg/docgen/lib/src/io.dart b/pkg/docgen/lib/src/io.dart
new file mode 100644
index 0000000..8d1a423
--- /dev/null
+++ b/pkg/docgen/lib/src/io.dart
@@ -0,0 +1,151 @@
+library io;
+/// This is a helper library to make working with io easier. 
+// TODO(janicejl): listDir, canonicalize, resolveLink, and linkExists are from  
+// pub/lib/src/io.dart. If the io.dart file becomes a package, should remove 
+// copy of the functions. 
+
+import 'dart:collection';
+import 'dart:io';
+import 'package:pathos/path.dart' as path;
+
+/// Lists the contents of [dir]. If [recursive] is `true`, lists subdirectory
+/// contents (defaults to `false`). If [includeHidden] is `true`, includes files
+/// and directories beginning with `.` (defaults to `false`).
+///
+/// The returned paths are guaranteed to begin with [dir].
+List<String> listDir(String dir, {bool recursive: false,
+    bool includeHidden: false}) {
+  List<String> doList(String dir, Set<String> listedDirectories) {
+    var contents = <String>[];
+
+    // Avoid recursive symlinks.
+    var resolvedPath = canonicalize(dir);
+    if (listedDirectories.contains(resolvedPath)) return [];
+
+    listedDirectories = new Set<String>.from(listedDirectories);
+    listedDirectories.add(resolvedPath);
+    
+    var children = <String>[];
+    for (var entity in new Directory(dir).listSync()) {
+      if (!includeHidden && path.basename(entity.path).startsWith('.')) {
+        continue;
+      }
+
+      contents.add(entity.path);
+      if (entity is Directory) {
+        // TODO(nweiz): don't manually recurse once issue 4794 is fixed.
+        // Note that once we remove the manual recursion, we'll need to
+        // explicitly filter out files in hidden directories.
+        if (recursive) {
+          children.addAll(doList(entity.path, listedDirectories));
+        }
+      }
+    }
+
+    contents.addAll(children);
+    return contents;
+  }
+
+  return doList(dir, new Set<String>());
+}
+
+/// Returns the canonical path for [pathString]. This is the normalized,
+/// absolute path, with symlinks resolved. As in [transitiveTarget], broken or
+/// recursive symlinks will not be fully resolved.
+///
+/// This doesn't require [pathString] to point to a path that exists on the
+/// filesystem; nonexistent or unreadable path entries are treated as normal
+/// directories.
+String canonicalize(String pathString) {
+  var seen = new Set<String>();
+  var components = new Queue<String>.from(
+      path.split(path.normalize(path.absolute(pathString))));
+
+  // The canonical path, built incrementally as we iterate through [components].
+  var newPath = components.removeFirst();
+
+  // Move through the components of the path, resolving each one's symlinks as
+  // necessary. A resolved component may also add new components that need to be
+  // resolved in turn.
+  while (!components.isEmpty) {
+    seen.add(path.join(newPath, path.joinAll(components)));
+    var resolvedPath = resolveLink(
+        path.join(newPath, components.removeFirst()));
+    var relative = path.relative(resolvedPath, from: newPath);
+
+    // If the resolved path of the component relative to `newPath` is just ".",
+    // that means component was a symlink pointing to its parent directory. We
+    // can safely ignore such components.
+    if (relative == '.') continue;
+
+    var relativeComponents = new Queue<String>.from(path.split(relative));
+
+    // If the resolved path is absolute relative to `newPath`, that means it's
+    // on a different drive. We need to canonicalize the entire target of that
+    // symlink again.
+    if (path.isAbsolute(relative)) {
+      // If we've already tried to canonicalize the new path, we've encountered
+      // a symlink loop. Avoid going infinite by treating the recursive symlink
+      // as the canonical path.
+      if (seen.contains(relative)) {
+        newPath = relative;
+      } else {
+        newPath = relativeComponents.removeFirst();
+        relativeComponents.addAll(components);
+        components = relativeComponents;
+      }
+      continue;
+    }
+
+    // Pop directories off `newPath` if the component links upwards in the
+    // directory hierarchy.
+    while (relativeComponents.first == '..') {
+      newPath = path.dirname(newPath);
+      relativeComponents.removeFirst();
+    }
+
+    // If there's only one component left, [resolveLink] guarantees that it's
+    // not a link (or is a broken link). We can just add it to `newPath` and
+    // continue resolving the remaining components.
+    if (relativeComponents.length == 1) {
+      newPath = path.join(newPath, relativeComponents.single);
+      continue;
+    }
+
+    // If we've already tried to canonicalize the new path, we've encountered a
+    // symlink loop. Avoid going infinite by treating the recursive symlink as
+    // the canonical path.
+    var newSubPath = path.join(newPath, path.joinAll(relativeComponents));
+    if (seen.contains(newSubPath)) {
+      newPath = newSubPath;
+      continue;
+    }
+
+    // If there are multiple new components to resolve, add them to the
+    // beginning of the queue.
+    relativeComponents.addAll(components);
+    components = relativeComponents;
+  }
+  return newPath;
+}
+
+/// Returns the transitive target of [link] (if A links to B which links to C,
+/// this will return C). If [link] is part of a symlink loop (e.g. A links to B
+/// which links back to A), this returns the path to the first repeated link (so
+/// `transitiveTarget("A")` would return `"A"` and `transitiveTarget("A")` would
+/// return `"B"`).
+///
+/// This accepts paths to non-links or broken links, and returns them as-is.
+String resolveLink(String link) {
+  var seen = new Set<String>();
+  while (linkExists(link) && !seen.contains(link)) {
+    seen.add(link);
+    link = path.normalize(path.join(
+        path.dirname(link), new Link(link).targetSync()));
+  }
+  return link;
+}
+
+/// Returns whether [link] exists on the file system. This will return `true`
+/// for any symlink, regardless of what it points at or whether it's broken.
+bool linkExists(String link) => new Link(link).existsSync();
\ No newline at end of file
diff --git a/pkg/docgen/pubspec.yaml b/pkg/docgen/pubspec.yaml
index 697f405..5a6e7af 100644
--- a/pkg/docgen/pubspec.yaml
+++ b/pkg/docgen/pubspec.yaml
@@ -1,4 +1,8 @@
 name: docgen
 description: A documentation generator for the Dart repository.
 dependencies:
-  markdown: any
\ No newline at end of file
+  args: any
+  logging: any
+  markdown: any
+  scheduled_test: any
+  unittest: any
diff --git a/pkg/http_server/lib/http_server.dart b/pkg/http_server/lib/http_server.dart
new file mode 100644
index 0000000..1dd07fc
--- /dev/null
+++ b/pkg/http_server/lib/http_server.dart
@@ -0,0 +1,14 @@
+// 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 http_server;
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:mime/mime.dart';
+
+part 'src/virtual_directory.dart';
+part 'src/virtual_host.dart';
+
diff --git a/pkg/http_server/lib/src/virtual_directory.dart b/pkg/http_server/lib/src/virtual_directory.dart
new file mode 100644
index 0000000..6ce667b
--- /dev/null
+++ b/pkg/http_server/lib/src/virtual_directory.dart
@@ -0,0 +1,284 @@
+// 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.
+
+part of http_server;
+
+/**
+ * A [VirtualDirectory] can serve files and directory-listing from a root path,
+ * to [HttpRequest]s.
+ *
+ * The [VirtualDirectory] providing secure handling of request uris and
+ * file-system links, correct mime-types and custom error pages.
+ */
+abstract class VirtualDirectory {
+  final String root;
+
+  /**
+   * Set or get if the [VirtualDirectory] should list the content of
+   * directories.
+   */
+  bool allowDirectoryListing = false;
+
+  /**
+   * Set or get if the [VirtualDirectory] should follow links, that point
+   * to other resources within the [root] directory.
+   */
+  bool followLinks = true;
+
+  /*
+   * Create a new [VirtualDirectory] for serving static file content of
+   * the path [root].
+   *
+   * The [root] is not required to exist. If the [root] doesn't exist at time of
+   * a request, a 404 is generated.
+   */
+  factory VirtualDirectory(String root) => new _VirtualDirectory(root);
+
+  /**
+   * Serve a [Stream] of [HttpRequest]s, in this [VirtualDirectory].
+   */
+  void serve(Stream<HttpRequest> requests);
+
+  /**
+   * Serve a single [HttpRequest], in this [VirtualDirectory].
+   */
+  void serveRequest(HttpRequest request);
+
+  /**
+   * Set the [callback] to override the error page handler. When [callback] is
+   * invoked, the `statusCode` property of the response is set.
+   */
+  void setErrorPageHandler(void callback(HttpRequest request));
+}
+
+class _VirtualDirectory implements VirtualDirectory {
+  final String root;
+
+  bool allowDirectoryListing = false;
+  bool followLinks = true;
+
+  Function _errorCallback;
+
+  _VirtualDirectory(this.root);
+
+  void serve(Stream<HttpRequest> requests) {
+    requests.listen(serveRequest);
+  }
+
+  void serveRequest(HttpRequest request) {
+    var path = new Path(request.uri.path).canonicalize();
+
+    if (!path.isAbsolute) {
+      return _serveErrorPage(HttpStatus.NOT_FOUND, request);
+    }
+
+    _locateResource(new Path('.'), path.segments())
+        .then((entity) {
+          if (entity == null) {
+            _serveErrorPage(HttpStatus.NOT_FOUND, request);
+            return;
+          }
+          if (entity is File) {
+            _serveFile(entity, request);
+          } else {
+            _serveErrorPage(HttpStatus.NOT_FOUND, request);
+          }
+        });
+  }
+
+  void setErrorPageHandler(void callback(HttpRequest request)) {
+    _errorCallback = callback;
+  }
+
+  Future<FileSystemEntity> _locateResource(Path path,
+                                           Iterable<String> segments) {
+    Path fullPath() => new Path(root).join(path);
+    return FileSystemEntity.type(fullPath().toNativePath(), followLinks: false)
+        .then((type) {
+          switch (type) {
+            case FileSystemEntityType.FILE:
+              if (segments.isEmpty) return new File.fromPath(fullPath());
+              break;
+
+            case FileSystemEntityType.DIRECTORY:
+              if (segments.isEmpty) {
+                if (allowDirectoryListing) {
+                  return new Directory.fromPath(fullPath());
+                }
+              } else {
+                return _locateResource(path.append(segments.first),
+                                       segments.skip(1));
+              }
+              break;
+
+            case FileSystemEntityType.LINK:
+              if (followLinks) {
+                return new Link.fromPath(fullPath()).target()
+                    .then((target) {
+                      var targetPath = new Path(target).canonicalize();
+                      if (targetPath.isAbsolute) return null;
+                      targetPath = path.directoryPath.join(targetPath)
+                          .canonicalize();
+                      if (targetPath.segments().isEmpty ||
+                          targetPath.segments().first == '..') return null;
+                      return _locateResource(targetPath.append(segments.first),
+                                             segments.skip(1));
+                    });
+              }
+              break;
+          }
+          // Return `null` on fall-through, to indicate NOT_FOUND.
+          return null;
+        });
+  }
+
+  void _serveFile(File file, HttpRequest request) {
+    var response = request.response;
+    // TODO(ajohnsen): Set up Zone support for these errors.
+    file.lastModified().then((lastModified) {
+      if (request.headers.ifModifiedSince != null &&
+          !lastModified.isAfter(request.headers.ifModifiedSince)) {
+        response.statusCode = HttpStatus.NOT_MODIFIED;
+        response.close();
+        return;
+      }
+
+      response.headers.set(HttpHeaders.LAST_MODIFIED, lastModified);
+      response.headers.set(HttpHeaders.ACCEPT_RANGES, "bytes");
+
+      if (request.method == 'HEAD') {
+        response.close();
+        return;
+      }
+
+      return file.length().then((length) {
+        String range = request.headers.value("range");
+        if (range != null) {
+          // We only support one range, where the standard support several.
+          Match matches = new RegExp(r"^bytes=(\d*)\-(\d*)$").firstMatch(range);
+          // If the range header have the right format, handle it.
+          if (matches != null) {
+            // Serve sub-range.
+            int start;
+            int end;
+            if (matches[1].isEmpty) {
+              start = matches[2].isEmpty ?
+                  length :
+                  length - int.parse(matches[2]);
+              end = length;
+            } else {
+              start = int.parse(matches[1]);
+              end = matches[2].isEmpty ? length : int.parse(matches[2]) + 1;
+            }
+
+            // Override Content-Length with the actual bytes sent.
+            response.headers.set(HttpHeaders.CONTENT_LENGTH, end - start);
+
+            // Set 'Partial Content' status code.
+            response.statusCode = HttpStatus.PARTIAL_CONTENT;
+            response.headers.set(HttpHeaders.CONTENT_RANGE,
+                                 "bytes $start-${end - 1}/$length");
+
+            // Pipe the 'range' of the file.
+            file.openRead(start, end)
+                .pipe(new _VirtualDirectoryFileStream(response, file.path))
+                .catchError((_) {});
+            return;
+          }
+        }
+
+        file.openRead()
+            .pipe(new _VirtualDirectoryFileStream(response, file.path))
+            .catchError((_) {});
+      });
+    }).catchError((_) {
+      response.close();
+    });
+  }
+
+  void _serveErrorPage(int error, HttpRequest request) {
+    var response = request.response;
+    response.statusCode = error;
+    if (_errorCallback != null) {
+      _errorCallback(request);
+      return;
+    }
+    // Default error page.
+    var path = request.uri.path;
+    var reason = response.reasonPhrase;
+    response.write(
+        '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\n');
+    response.writeln(
+        '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">');
+    response.writeln('<html xmlns="http://www.w3.org/1999/xhtml">');
+    response.writeln('<head>');
+    response.writeln('<title>$reason: $path</title>');
+    response.writeln('</head>');
+    response.writeln('<body>');
+    response.writeln('<h1>Error $error at \'$path\': $reason</h1>');
+    var server = response.headers.value(HttpHeaders.SERVER);
+    if (server != null) {
+      response.writeln(server);
+    }
+    response.writeln('</body>');
+    response.writeln('</html>');
+    response.close();
+  }
+}
+
+class _VirtualDirectoryFileStream extends StreamConsumer<List<int>> {
+  final HttpResponse response;
+  final String path;
+  var buffer = [];
+
+  _VirtualDirectoryFileStream(HttpResponse this.response, String this.path);
+
+  Future addStream(Stream<List<int>> stream) {
+    stream.listen(
+        (data) {
+          if (buffer == null) {
+            response.add(data);
+            return;
+          }
+          if (buffer.length == 0) {
+            if (data.length >= defaultMagicNumbersMaxLength) {
+              setMimeType(data);
+              response.add(data);
+              buffer = null;
+            } else {
+              buffer.addAll(data);
+            }
+          } else {
+            buffer.addAll(data);
+            if (buffer.length >= defaultMagicNumbersMaxLength) {
+              setMimeType(buffer);
+              response.add(buffer);
+              buffer = null;
+            }
+          }
+        },
+        onDone: () {
+          if (buffer != null) {
+            if (buffer.length == 0) {
+              setMimeType(null);
+            } else {
+              setMimeType(buffer);
+              response.add(buffer);
+            }
+          }
+          response.close();
+        },
+        onError: response.addError);
+    return response.done;
+  }
+
+  Future close() => new Future.value();
+
+  void setMimeType(var bytes) {
+    var mimeType = lookupMimeType(path, headerBytes: bytes);
+    if (mimeType != null) {
+      response.headers.contentType = ContentType.parse(mimeType);
+    }
+  }
+}
diff --git a/pkg/http_server/lib/src/virtual_host.dart b/pkg/http_server/lib/src/virtual_host.dart
new file mode 100644
index 0000000..4c67eca
--- /dev/null
+++ b/pkg/http_server/lib/src/virtual_host.dart
@@ -0,0 +1,149 @@
+// 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.
+
+part of http_server;
+
+
+/**
+ * The [VirtualHost] class is a utility class for handling multiple hosts on
+ * multiple sources, by using a named-based approach.
+ */
+abstract class VirtualHost {
+  /**
+   * Get the [Stream] of [HttpRequest]s, not matching any hosts. If unused, the
+   * default implementation will result in a [HttpHeaders.FORBIDDEN] response.
+   */
+  Stream<HttpRequest> get unhandled;
+
+  /**
+   * Construct a new [VirtualHost].
+   *
+   * The optional [source] is a shortcut for calling [addSource].
+   *
+   * Example of usage:
+   *
+   *   HttpServer.bind(..., 80).then((server) {
+   *     var virtualHost = new VirtualHost(server);
+   *     virtualServer.addHost('static.myserver.com')
+   *         .listen(...);
+   *     virtualServer.addHost('cache.myserver.com')
+   *         .listen(...);
+   *   })
+   */
+  factory VirtualHost([Stream<HttpRequest> source]) => new _VirtualHost(source);
+
+  /**
+   * Provide another source of [HttpRequest]s in the form of a [Stream].
+   */
+  void addSource(Stream<HttpRequest> source);
+
+
+  /**
+   * Add a host to the [VirtualHost] instance. The host can be either a specific
+   * domain (`my.domain.name`) or a wildcard-based domain name
+   * (`*.domain.name`). The former will only match the specific domain name
+   * while the latter will match any series of sub-domains.
+   *
+   * If both `my.domain.name` and `*.domain.name` is specified, the most
+   * qualified will take precedence, `my.domain.name` in this case.
+   */
+  Stream<HttpRequest> addHost(String host);
+}
+
+
+class _VirtualHostDomain {
+  StreamController<HttpRequest> any;
+  StreamController<HttpRequest> exact;
+  Map<String, _VirtualHostDomain> subDomains = {};
+}
+
+
+class _VirtualHost implements VirtualHost {
+  final _VirtualHostDomain _topDomain = new _VirtualHostDomain();
+  StreamController<HttpRequest> _unhandledController;
+
+  Stream<HttpRequest> get unhandled {
+    if (_unhandledController == null) {
+      _unhandledController = new StreamController<HttpRequest>();
+    }
+    return _unhandledController.stream;
+  }
+
+  _VirtualHost([Stream<HttpRequest> source]) {
+    if (source != null) addSource(source);
+  }
+
+  void addSource(Stream<HttpRequest> source) {
+    source.listen((request) {
+      var host = request.headers.host;
+      if (host == null) {
+        _unhandled(request);
+        return;
+      }
+      var domains = host.split('.');
+      var current = _topDomain;
+      var any;
+      for (var i = domains.length - 1; i >= 0; i--) {
+        if (current.any != null) any = current.any;
+        if (i == 0) {
+          var last = current.subDomains[domains[i]];
+          if (last != null && last.exact != null) {
+            last.exact.add(request);
+            return;
+          }
+        } else {
+          if (!current.subDomains.containsKey(domains[i])) {
+            break;
+          }
+          current = current.subDomains[domains[i]];
+        }
+      }
+      if (any != null) {
+        any.add(request);
+        return;
+      }
+      _unhandled(request);
+    });
+  }
+
+  Stream<HttpRequest> addHost(String host) {
+    if (host.lastIndexOf('*') > 0) {
+      throw new ArgumentError(
+          'Wildcards are only allowed in the beginning of a host');
+    }
+    var controller = new StreamController<HttpRequest>();
+    var domains = host.split('.');
+    var current = _topDomain;
+    for (var i = domains.length - 1; i >= 0; i--) {
+      if (domains[i] == '*') {
+        if (current.any != null) {
+          throw new ArgumentError('Host is already provided');
+        }
+        current.any = controller;
+      } else {
+        if (!current.subDomains.containsKey(domains[i])) {
+          current.subDomains[domains[i]] = new _VirtualHostDomain();
+        }
+        if (i > 0) {
+          current = current.subDomains[domains[i]];
+        } else {
+          if (current.subDomains[domains[i]].exact != null) {
+            throw new ArgumentError('Host is already provided');
+          }
+          current.subDomains[domains[i]].exact = controller;
+        }
+      }
+    }
+    return controller.stream;
+  }
+
+  void _unhandled(HttpRequest request) {
+    if (_unhandledController != null) {
+      _unhandledController.add(request);
+      return;
+    }
+    request.response.statusCode = HttpStatus.FORBIDDEN;
+    request.response.close();
+  }
+}
diff --git a/pkg/http_server/pubspec.yaml b/pkg/http_server/pubspec.yaml
new file mode 100644
index 0000000..3f29100
--- /dev/null
+++ b/pkg/http_server/pubspec.yaml
@@ -0,0 +1,7 @@
+name: http_server
+author: "Dart Team <misc@dartlang.org>"
+homepage: http://www.dartlang.org
+description: >
+ Library of HTTP server classes.
+dependencies:
+  mime: any
diff --git a/pkg/http_server/test/pkcert/README b/pkg/http_server/test/pkcert/README
new file mode 100644
index 0000000..fe764a9
--- /dev/null
+++ b/pkg/http_server/test/pkcert/README
@@ -0,0 +1,16 @@
+This is a certificate database used by Dart for testing purposes.
+
+It is created as a certificate database by NSS (Network Security Services),
+a library from Mozilla, using the certutil tool.  It uses a cert9.db file,
+rather than a cert8.db file, so the database directory must be specified with
+"sql:" in front of the directory path, or the environment variable
+NSS_DEFAULT_DB_TYPE must be set to "sql".
+
+The password for the key database is "dartdart".
+
+The database contains a root certificate from Equifax, used to verify the
+client https connection to www.google.dk.  It contains a self-signed
+certificate for a local certificate authority myauthority_cert, and a
+server certificate for localhost called localhost_cert, signed by
+myauthority_cert.  It contains the key for localhost_cert, but
+not the key for myauthority_cert.
diff --git a/pkg/http_server/test/pkcert/cert9.db b/pkg/http_server/test/pkcert/cert9.db
new file mode 100644
index 0000000..497fca6
--- /dev/null
+++ b/pkg/http_server/test/pkcert/cert9.db
Binary files differ
diff --git a/pkg/http_server/test/pkcert/key4.db b/pkg/http_server/test/pkcert/key4.db
new file mode 100644
index 0000000..fc06432
--- /dev/null
+++ b/pkg/http_server/test/pkcert/key4.db
Binary files differ
diff --git a/pkg/http_server/test/utils.dart b/pkg/http_server/test/utils.dart
new file mode 100644
index 0000000..fb8e037
--- /dev/null
+++ b/pkg/http_server/test/utils.dart
@@ -0,0 +1,55 @@
+// 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 utils;
+
+import 'dart:async';
+import 'dart:io';
+
+
+Future<int> getStatusCode(int port,
+                          String path,
+                          {String host,
+                           bool secure: false,
+                           DateTime ifModifiedSince}) {
+  var uri = (secure ?
+      new Uri.https('localhost:$port', path) :
+      new Uri.http('localhost:$port', path));
+  return new HttpClient().getUrl(uri)
+      .then((request) {
+        if (host != null) request.headers.host = host;
+        if (ifModifiedSince != null) {
+          request.headers.ifModifiedSince = ifModifiedSince;
+        }
+        return request.close();
+      })
+      .then((response) => response.drain().then(
+          (_) => response.statusCode));
+}
+
+
+Future<HttpHeaders> getHeaders(int port, String path) {
+  return new HttpClient().get('localhost', port, path)
+      .then((request) => request.close())
+      .then((response) => response.drain().then(
+          (_) => response.headers));
+}
+
+
+Future<String> getAsString(int port, String path) {
+  return new HttpClient().get('localhost', port, path)
+      .then((request) => request.close())
+      .then((response) => StringDecoder.decode(response));
+}
+
+
+const CERTIFICATE = "localhost_cert";
+
+
+setupSecure() {
+  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path certificateDatabase = scriptDir.append('pkcert');
+  SecureSocket.initialize(database: certificateDatabase.toNativePath(),
+                          password: 'dartdart');
+}
diff --git a/pkg/http_server/test/virtual_directory_test.dart b/pkg/http_server/test/virtual_directory_test.dart
new file mode 100644
index 0000000..1c579da
--- /dev/null
+++ b/pkg/http_server/test/virtual_directory_test.dart
@@ -0,0 +1,367 @@
+// 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 'dart:async';
+import 'dart:io';
+
+import "package:unittest/unittest.dart";
+import "package:http_server/http_server.dart";
+
+import 'utils.dart';
+
+
+void main() {
+  group('serve-root', () {
+    test('dir-exists', () {
+      expect(HttpServer.bind('localhost', 0).then((server) {
+        var dir = new Directory('').createTempSync();
+        var virDir = new VirtualDirectory(dir.path);
+
+        virDir.serve(server);
+
+        return getStatusCode(server.port, '/')
+            .whenComplete(() {
+              server.close();
+              dir.deleteSync();
+            });
+      }), completion(equals(HttpStatus.NOT_FOUND)));
+    });
+
+    test('dir-not-exists', () {
+      expect(HttpServer.bind('localhost', 0).then((server) {
+        var dir = new Directory('').createTempSync();
+        dir.deleteSync();
+        var virDir = new VirtualDirectory(dir.path);
+
+        virDir.serve(server);
+
+        return getStatusCode(server.port, '/')
+            .whenComplete(() {
+              server.close();
+            });
+      }), completion(equals(HttpStatus.NOT_FOUND)));
+    });
+  });
+
+  group('serve-file', () {
+    group('top-level', () {
+      test('file-exists', () {
+        expect(HttpServer.bind('localhost', 0).then((server) {
+          var dir = new Directory('').createTempSync();
+          var file = new File('${dir.path}/file')..createSync();
+          var virDir = new VirtualDirectory(dir.path);
+
+          virDir.serve(server);
+
+          return getStatusCode(server.port, '/file')
+              .whenComplete(() {
+                server.close();
+                dir.deleteSync(recursive: true);
+              });
+        }), completion(equals(HttpStatus.OK)));
+      });
+
+      test('file-not-exists', () {
+        expect(HttpServer.bind('localhost', 0).then((server) {
+          var dir = new Directory('').createTempSync();
+          var virDir = new VirtualDirectory(dir.path);
+
+          virDir.serve(server);
+
+          return getStatusCode(server.port, '/file')
+              .whenComplete(() {
+                server.close();
+                dir.deleteSync();
+              });
+        }), completion(equals(HttpStatus.NOT_FOUND)));
+      });
+    });
+
+    group('in-dir', () {
+      test('file-exists', () {
+        expect(HttpServer.bind('localhost', 0).then((server) {
+          var dir = new Directory('').createTempSync();
+          var dir2 = new Directory('${dir.path}/dir')..createSync();
+          var file = new File('${dir2.path}/file')..createSync();
+          var virDir = new VirtualDirectory(dir.path);
+
+          virDir.serve(server);
+
+          return getStatusCode(server.port, '/dir/file')
+              .whenComplete(() {
+                server.close();
+                dir.deleteSync(recursive: true);
+              });
+        }), completion(equals(HttpStatus.OK)));
+      });
+
+      test('file-not-exists', () {
+        expect(HttpServer.bind('localhost', 0).then((server) {
+          var dir = new Directory('').createTempSync();
+          var dir2 = new Directory('${dir.path}/dir')..createSync();
+          var file = new File('${dir.path}/file')..createSync();
+          var virDir = new VirtualDirectory(dir.path);
+
+          virDir.serve(server);
+
+          return getStatusCode(server.port, '/dir/file')
+              .whenComplete(() {
+                server.close();
+                dir.deleteSync(recursive: true);
+              });
+        }), completion(equals(HttpStatus.NOT_FOUND)));
+      });
+    });
+  });
+
+  group('links', () {
+    if (!Platform.isWindows) {
+      group('follow-links', () {
+        test('dir-link', () {
+          expect(HttpServer.bind('localhost', 0).then((server) {
+            var dir = new Directory('').createTempSync();
+            var dir2 = new Directory('${dir.path}/dir2')..createSync();
+            var link = new Link('${dir.path}/dir3')..createSync('dir2');
+            var file = new File('${dir2.path}/file')..createSync();
+            var virDir = new VirtualDirectory(dir.path);
+            virDir.followLinks = true;
+
+            virDir.serve(server);
+
+            return getStatusCode(server.port, '/dir3/file')
+                .whenComplete(() {
+                  server.close();
+                  dir.deleteSync(recursive: true);
+                });
+          }), completion(equals(HttpStatus.OK)));
+        });
+
+        test('root-link', () {
+          expect(HttpServer.bind('localhost', 0).then((server) {
+            var dir = new Directory('').createTempSync();
+            var link = new Link('${dir.path}/dir3')..createSync('.');
+            var file = new File('${dir.path}/file')..createSync();
+            var virDir = new VirtualDirectory(dir.path);
+            virDir.followLinks = true;
+
+            virDir.serve(server);
+
+            return getStatusCode(server.port, '/dir3/file')
+                .whenComplete(() {
+                  server.close();
+                  dir.deleteSync(recursive: true);
+                });
+          }), completion(equals(HttpStatus.OK)));
+        });
+
+        group('bad-links', () {
+          test('absolute-link', () {
+            expect(HttpServer.bind('localhost', 0).then((server) {
+              var dir = new Directory('').createTempSync();
+              var file = new File('${dir.path}/file')..createSync();
+              var link = new Link('${dir.path}/dir3')
+                  ..createSync('${dir.path}/file');
+              var virDir = new VirtualDirectory(dir.path);
+              virDir.followLinks = true;
+
+              virDir.serve(server);
+
+              return new HttpClient().get('localhost',
+                                          server.port,
+                                          '/dir3/file')
+                  .then((request) => request.close())
+                  .then((response) => response.drain().then(
+                      (_) => response.statusCode))
+                  .whenComplete(() {
+                    server.close();
+                    dir.deleteSync(recursive: true);
+                  });
+            }), completion(equals(HttpStatus.NOT_FOUND)));
+          });
+
+          test('relative-parent-link', () {
+            expect(HttpServer.bind('localhost', 0).then((server) {
+              var dir = new Directory('').createTempSync();
+              var name = new Path(dir.path).filename;
+              var file = new File('${dir.path}/file')..createSync();
+              var link = new Link('${dir.path}/dir3')
+                  ..createSync('../$name/file');
+              var virDir = new VirtualDirectory(dir.path);
+              virDir.followLinks = true;
+
+              virDir.serve(server);
+
+              return new HttpClient().get('localhost',
+                                          server.port,
+                                          '/dir3/file')
+                  .then((request) => request.close())
+                  .then((response) => response.drain().then(
+                      (_) => response.statusCode))
+                  .whenComplete(() {
+                    server.close();
+                    dir.deleteSync(recursive: true);
+                  });
+            }), completion(equals(HttpStatus.NOT_FOUND)));
+          });
+        });
+      });
+
+      group('not-follow-links', () {
+        test('dir-link', () {
+          expect(HttpServer.bind('localhost', 0).then((server) {
+            var dir = new Directory('').createTempSync();
+            var dir2 = new Directory('${dir.path}/dir2')..createSync();
+            var link = new Link('${dir.path}/dir3')..createSync('dir2');
+            var file = new File('${dir2.path}/file')..createSync();
+            var virDir = new VirtualDirectory(dir.path);
+            virDir.followLinks = false;
+
+            virDir.serve(server);
+
+            return getStatusCode(server.port, '/dir3/file')
+                .whenComplete(() {
+                  server.close();
+                  dir.deleteSync(recursive: true);
+                });
+          }), completion(equals(HttpStatus.NOT_FOUND)));
+        });
+      });
+    }
+  });
+
+  group('last-modified', () {
+    group('file', () {
+      test('file-exists', () {
+        expect(HttpServer.bind('localhost', 0).then((server) {
+          var dir = new Directory('').createTempSync();
+          var file = new File('${dir.path}/file')..createSync();
+          var virDir = new VirtualDirectory(dir.path);
+
+          virDir.serve(server);
+
+          return getHeaders(server.port, '/file')
+              .then((headers) {
+                expect(headers.value(HttpHeaders.LAST_MODIFIED), isNotNull);
+                return HttpDate.parse(
+                    headers.value(HttpHeaders.LAST_MODIFIED));
+              })
+              .then((lastModified) {
+                return getStatusCode(
+                    server.port, '/file', ifModifiedSince: lastModified);
+              })
+              .whenComplete(() {
+                server.close();
+                dir.deleteSync(recursive: true);
+              });
+        }), completion(equals(HttpStatus.NOT_MODIFIED)));
+      });
+
+      test('file-changes', () {
+        expect(HttpServer.bind('localhost', 0).then((server) {
+          var dir = new Directory('').createTempSync();
+          var file = new File('${dir.path}/file')..createSync();
+          var virDir = new VirtualDirectory(dir.path);
+
+          virDir.serve(server);
+
+          return getHeaders(server.port, '/file')
+              .then((headers) {
+                expect(headers.value(HttpHeaders.LAST_MODIFIED), isNotNull);
+                return HttpDate.parse(
+                    headers.value(HttpHeaders.LAST_MODIFIED));
+              })
+              .then((lastModified) {
+                // Fake file changed by moving date back in time.
+                lastModified = lastModified.subtract(
+                  const Duration(seconds: 10));
+                return getStatusCode(
+                    server.port, '/file', ifModifiedSince: lastModified);
+              })
+              .whenComplete(() {
+                server.close();
+                dir.deleteSync(recursive: true);
+              });
+        }), completion(equals(HttpStatus.OK)));
+      });
+    });
+  });
+
+  group('content-type', () {
+    group('mime-type', () {
+      test('from-path', () {
+        expect(HttpServer.bind('localhost', 0).then((server) {
+          var dir = new Directory('').createTempSync();
+          var file = new File('${dir.path}/file.jpg')..createSync();
+          var virDir = new VirtualDirectory(dir.path);
+
+          virDir.serve(server);
+
+          return getHeaders(server.port, '/file.jpg')
+              .then((headers) => headers.contentType.toString())
+              .whenComplete(() {
+                server.close();
+                dir.deleteSync(recursive: true);
+              });
+        }), completion(equals('image/jpeg')));
+      });
+
+      test('from-magic-number', () {
+        expect(HttpServer.bind('localhost', 0).then((server) {
+          var dir = new Directory('').createTempSync();
+          var file = new File('${dir.path}/file.jpg')..createSync();
+          file.writeAsBytesSync(
+              [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
+          var virDir = new VirtualDirectory(dir.path);
+
+          virDir.serve(server);
+
+          return getHeaders(server.port, '/file.jpg')
+              .then((headers) => headers.contentType.toString())
+              .whenComplete(() {
+                server.close();
+                dir.deleteSync(recursive: true);
+              });
+        }), completion(equals('image/png')));
+      });
+    });
+  });
+
+  group('error-page', () {
+    test('default', () {
+      expect(HttpServer.bind('localhost', 0).then((server) {
+        var dir = new Directory('').createTempSync();
+        var virDir = new VirtualDirectory(dir.path);
+        dir.deleteSync();
+
+        virDir.serve(server);
+
+        return getAsString(server.port, '/')
+            .whenComplete(() {
+              server.close();
+            });
+      }), completion(matches(new RegExp('404.*Not Found'))));
+    });
+
+    test('custom', () {
+      expect(HttpServer.bind('localhost', 0).then((server) {
+        var dir = new Directory('').createTempSync();
+        var virDir = new VirtualDirectory(dir.path);
+        dir.deleteSync();
+
+        virDir.setErrorPageHandler((request) {
+          request.response.write('my-page ');
+          request.response.write(request.response.statusCode);
+          request.response.close();
+        });
+        virDir.serve(server);
+
+        return getAsString(server.port, '/')
+            .whenComplete(() {
+              server.close();
+            });
+      }), completion(equals('my-page 404')));
+    });
+  });
+}
+
diff --git a/pkg/http_server/test/virtual_host_test.dart b/pkg/http_server/test/virtual_host_test.dart
new file mode 100644
index 0000000..a08e793
--- /dev/null
+++ b/pkg/http_server/test/virtual_host_test.dart
@@ -0,0 +1,181 @@
+// 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 'dart:async';
+import 'dart:io';
+
+import "package:unittest/unittest.dart";
+import "package:http_server/http_server.dart";
+
+import 'utils.dart';
+
+void main() {
+  setupSecure();
+
+  test('empty-host', () {
+    expect(HttpServer.bind('localhost', 0).then((server) {
+      var virHost = new VirtualHost(server);
+      return getStatusCode(server.port, '/')
+          .whenComplete(server.close);
+    }), completion(equals(HttpStatus.FORBIDDEN)));
+  });
+
+  test('empty-host-unhandled', () {
+    expect(HttpServer.bind('localhost', 0).then((server) {
+      var virHost = new VirtualHost(server);
+      expect(virHost.unhandled.first.then((request) {
+        request.response.close();
+      }), completion(isNull));
+      return getStatusCode(server.port, '/')
+          .whenComplete(server.close);
+    }), completion(equals(HttpStatus.OK)));
+  });
+
+  test('single-host', () {
+    expect(HttpServer.bind('localhost', 0).then((server) {
+      var virHost = new VirtualHost(server);
+      expect(virHost.addHost('*.host.com').first.then((request) {
+        request.response.close();
+      }), completion(isNull));
+      return getStatusCode(server.port, '/', host: 'my.host.com')
+          .whenComplete(server.close);
+    }), completion(equals(HttpStatus.OK)));
+  });
+
+  test('multiple-host', () {
+    expect(HttpServer.bind('localhost', 0).then((server) {
+      var virHost = new VirtualHost(server);
+      expect(virHost.addHost('*.host1.com').first.then((request) {
+        request.response.close();
+      }), completion(isNull));
+      expect(virHost.addHost('*.host2.com').first.then((request) {
+        request.response.close();
+      }), completion(isNull));
+      expect(virHost.addHost('*.host3.com').first.then((request) {
+        request.response.close();
+      }), completion(isNull));
+      return Future.wait([
+          getStatusCode(server.port, '/', host: 'my.host1.com'),
+          getStatusCode(server.port, '/', host: 'my.host2.com'),
+          getStatusCode(server.port, '/', host: 'my.host3.com')])
+          .whenComplete(server.close);
+    }), completion(equals([HttpStatus.OK, HttpStatus.OK, HttpStatus.OK])));
+  });
+
+  test('multiple-source-https', () {
+    expect(Future.wait([
+        HttpServer.bind('localhost', 0),
+        HttpServer.bindSecure('localhost', 0, certificateName: CERTIFICATE)])
+        .then((servers) {
+      var virHost = new VirtualHost();
+      virHost.addSource(servers[0]);
+      virHost.addSource(servers[1]);
+      virHost.unhandled.listen((request) {
+        request.response.close();
+      });
+      return Future.wait([
+          getStatusCode(servers[0].port, '/', host: 'myhost1.com'),
+          getStatusCode(
+              servers[1].port, '/', host: 'myhost2.com', secure: true)])
+          .whenComplete(() => servers.forEach((s) => s.close()));
+    }), completion(equals([HttpStatus.OK, HttpStatus.OK])));
+  });
+
+  group('domain', () {
+    test('specific-sub-domain', () {
+      expect(HttpServer.bind('localhost', 0).then((server) {
+        var virHost = new VirtualHost(server);
+        expect(virHost.addHost('my1.host.com').first.then((request) {
+          request.response.close();
+        }), completion(isNull));
+        expect(virHost.addHost('my2.host.com').first.then((request) {
+          request.response.close();
+        }), completion(isNull));
+        expect(virHost.addHost('my3.host.com').first.then((request) {
+          request.response.close();
+        }), completion(isNull));
+        return Future.wait([
+            getStatusCode(server.port, '/', host: 'my1.host.com'),
+            getStatusCode(server.port, '/', host: 'my2.host.com'),
+            getStatusCode(server.port, '/', host: 'my3.host.com')])
+            .whenComplete(server.close);
+      }), completion(equals([HttpStatus.OK, HttpStatus.OK, HttpStatus.OK])));
+    });
+
+    test('wildcard-sub-domain', () {
+      expect(HttpServer.bind('localhost', 0).then((server) {
+        var virHost = new VirtualHost(server);
+        expect(virHost.addHost('*.host1.com').first.then((request) {
+          request.response.close();
+        }), completion(isNull));
+        expect(virHost.addHost('*.host2.com').first.then((request) {
+          request.response.close();
+        }), completion(isNull));
+        expect(virHost.addHost('*.host3.com').first.then((request) {
+          request.response.close();
+        }), completion(isNull));
+        return Future.wait([
+            getStatusCode(server.port, '/', host: 'my.host1.com'),
+            getStatusCode(server.port, '/', host: 'my.host2.com'),
+            getStatusCode(server.port, '/', host: 'my.host3.com')])
+            .whenComplete(server.close);
+      }), completion(equals([HttpStatus.OK, HttpStatus.OK, HttpStatus.OK])));
+    });
+
+    test('mix-sub-domain', () {
+      expect(HttpServer.bind('localhost', 0).then((server) {
+        var virHost = new VirtualHost(server);
+        expect(virHost.addHost('my1.host.com').first.then((request) {
+          request.response.close();
+        }), completion(isNull));
+        expect(virHost.addHost('my2.host.com').first.then((request) {
+          request.response.close();
+        }), completion(isNull));
+        expect(virHost.addHost('*.host.com').first.then((request) {
+          request.response.close();
+        }), completion(isNull));
+        return Future.wait([
+            getStatusCode(server.port, '/', host: 'my1.host.com'),
+            getStatusCode(server.port, '/', host: 'my2.host.com'),
+            getStatusCode(server.port, '/', host: 'my3.host.com')])
+            .whenComplete(server.close);
+      }), completion(equals([HttpStatus.OK, HttpStatus.OK, HttpStatus.OK])));
+    });
+
+
+    test('wildcard', () {
+      expect(HttpServer.bind('localhost', 0).then((server) {
+        var virHost = new VirtualHost(server);
+        expect(virHost.addHost('*').first.then((request) {
+          request.response.close();
+        }), completion(isNull));
+        expect(virHost.addHost('*.com').first.then((request) {
+          request.response.close();
+        }), completion(isNull));
+        expect(virHost.addHost('*.host.com').first.then((request) {
+          request.response.close();
+        }), completion(isNull));
+        return Future.wait([
+            getStatusCode(server.port, '/', host: 'some.host.dk'),
+            getStatusCode(server.port, '/', host: 'my.host2.com'),
+            getStatusCode(server.port, '/', host: 'long.sub.of.host.com')])
+            .whenComplete(server.close);
+      }), completion(equals([HttpStatus.OK, HttpStatus.OK, HttpStatus.OK])));
+    });
+
+    test('duplicate-domain', () {
+      var virHost = new VirtualHost();
+      virHost.addHost('my1.host.com');
+      expect(() => (virHost.addHost('my1.host.com')), throwsArgumentError);
+      virHost.addHost('*.host.com');
+      expect(() => (virHost.addHost('*.host.com')), throwsArgumentError);
+      virHost.addHost('my2.host.com');
+      virHost.addHost('my3.host.com');
+      virHost.addHost('*.com');
+      virHost.addHost('*');
+      expect(() => (virHost.addHost('*')), throwsArgumentError);
+    });
+  });
+}
+
diff --git a/pkg/intl/lib/extract_messages.dart b/pkg/intl/lib/extract_messages.dart
index fc8bd09..1ca9e13 100755
--- a/pkg/intl/lib/extract_messages.dart
+++ b/pkg/intl/lib/extract_messages.dart
@@ -201,9 +201,9 @@
 
   void reportErrorLocation(ASTNode node) {
     if (origin != null) print("    from $origin");
-    LineInfo info = root.lineInfo;
+    var info = root.lineInfo;
     if (info != null) {
-      LineInfo_Location line = info.getLocation(node.offset);
+      var line = info.getLocation(node.offset);
       print("    line: ${line.lineNumber}, column: ${line.columnNumber}");
     }
   }
diff --git a/pkg/intl/lib/generate_localized.dart b/pkg/intl/lib/generate_localized.dart
index c40d1f6..f6a4225 100644
--- a/pkg/intl/lib/generate_localized.dart
+++ b/pkg/intl/lib/generate_localized.dart
@@ -86,22 +86,22 @@
   var result = new StringBuffer();
   locale = new IntlMessage().escapeAndValidate(locale, locale);
   result.write(prologue(locale));
-  for (var each in translations) {
-    var message = each.originalMessage;
-    if (each.message != null) {
-      message.addTranslation(locale, each.message);
-    }
+  // Exclude messages with no translation and translations with no matching
+  // original message (e.g. if we're using some messages from a larger catalog)
+  var usableTranslations =  translations.where(
+      (each) => each.originalMessage != null && each.message != null).toList();
+  for (var each in usableTranslations) {
+      each.originalMessage.addTranslation(locale, each.message);
   }
-  var sorted = translations.where((each) => each.message != null).toList();
-  sorted.sort((a, b) =>
+  usableTranslations.sort((a, b) =>
       a.originalMessage.name.compareTo(b.originalMessage.name));
-  for (var each in sorted) {
+  for (var each in usableTranslations) {
     result.write("  ");
     result.write(each.originalMessage.toCode(locale));
     result.write("\n\n");
   }
   result.write("\n  final messages = const {\n");
-  var entries = sorted
+  var entries = usableTranslations
       .map((translation) => translation.originalMessage.name)
       .map((name) => "    \"$name\" : $name");
   result.write(entries.join(",\n"));
diff --git a/pkg/intl/test/intl_message_basic_example_test.dart b/pkg/intl/test/intl_message_basic_example_test.dart
index d89ccd8..e9281ee 100644
--- a/pkg/intl/test/intl_message_basic_example_test.dart
+++ b/pkg/intl/test/intl_message_basic_example_test.dart
@@ -12,30 +12,28 @@
 import 'package:unittest/unittest.dart';
 import 'dart:async';
 
-List list;
-
 main() {
-  list = [];
-  setup(runAllTests, addToList);
-}
+  var list = [];
+  var waitForIt = new Completer();
 
-var waitForIt = new Completer();
+  addToList(x) {
+    list.add(x);
+    if (list.length == 4) {
+      waitForIt.complete(list);
+    }
+  }
 
-addToList(x) {
-  list.add(x);
-  if (list.length == 4) waitForIt.complete(list);
-}
-
-runAllTests(_) {
-  setup(runProgram, addToList);
-  waitForIt.future.then(actuallyRunTheTests);
-}
-
-actuallyRunTheTests(_) {
   test('Verify basic example printing localized messages', () {
-    expect(list[0], "Ran at 00:00:00 on Thursday, January 1, 1970");
-    expect(list[1], "Ausgedruckt am 00:00:00 am Donnerstag, 1. Januar 1970.");
-    expect(list[2], "วิ่ง 0:00:00 on วันพฤหัสบดี 1 มกราคม 1970.");
-    expect(list[3], "วิ่ง now on today.");
+    runAllTests(_) {
+      setup(expectAsync1(runProgram), addToList);
+    }
+    setup(expectAsync1(runAllTests), addToList);
+    waitForIt.future.then(expectAsync1((_) {
+      expect(list[0], "Ran at 00:00:00 on Thursday, January 1, 1970");
+      expect(list[1], "Ausgedruckt am 00:00:00 am Donnerstag, 1. Januar 1970.");
+      expect(list[2], "วิ่ง 0:00:00 on วันพฤหัสบดี 1 มกราคม 1970.");
+      expect(list[3], "วิ่ง now on today.");
+    }));
   });
 }
+
diff --git a/pkg/intl/test/message_extraction/extract_to_json.dart b/pkg/intl/test/message_extraction/extract_to_json.dart
index 5b6f316..ce5c907 100644
--- a/pkg/intl/test/message_extraction/extract_to_json.dart
+++ b/pkg/intl/test/message_extraction/extract_to_json.dart
@@ -34,9 +34,8 @@
   parser.addFlag("suppress-warnings", defaultsTo: false,
       callback: (x) => suppressWarnings = x);
 
-  void setTargetDir(value) => targetDir = value;
-
-  parser.addOption("output-dir", defaultsTo: '.', callback: setTargetDir);
+  parser.addOption("output-dir", defaultsTo: '.',
+      callback: (value) => targetDir = value);
   parser.parse(args);
   if (args.length == 0) {
     print('Usage: extract_to_json [--output-dir=<dir>] [files.dart]');
diff --git a/pkg/intl/test/message_extraction/generate_from_json.dart b/pkg/intl/test/message_extraction/generate_from_json.dart
index 0759507..c991a44 100644
--- a/pkg/intl/test/message_extraction/generate_from_json.dart
+++ b/pkg/intl/test/message_extraction/generate_from_json.dart
@@ -43,8 +43,8 @@
   parser.parse(args);
   if (args.length == 0) {
     print('Usage: generate_from_json [--output-dir=<dir>]'
-        ' [generated-file-prefix=<prefix>] file1.dart file2.dart ...'
-        ' outputFile.json');
+        ' [--generated-file-prefix=<prefix>] file1.dart file2.dart ...'
+        ' translation1.json translation2.json ...');
     exit(0);
   }
 
diff --git a/pkg/intl/test/message_extraction/message_extraction_test.dart b/pkg/intl/test/message_extraction/message_extraction_test.dart
index 85e0323..c8bd55ab 100644
--- a/pkg/intl/test/message_extraction/message_extraction_test.dart
+++ b/pkg/intl/test/message_extraction/message_extraction_test.dart
@@ -10,7 +10,7 @@
 import 'package:pathos/path.dart' as path;
 import '../data_directory.dart';
 
-final dart = new Options().executable;
+final dart = Platform.executable;
 
 // TODO(alanknight): We have no way of knowing what the package-root is,
 // so when we're running under the test framework, which sets the
diff --git a/pkg/logging/lib/logging.dart b/pkg/logging/lib/logging.dart
index b29f076c..3c841dc 100644
--- a/pkg/logging/lib/logging.dart
+++ b/pkg/logging/lib/logging.dart
@@ -153,10 +153,9 @@
    * [Level.INFO], [Level.WARNING], etc) you can use their specialized methods
    * instead (e.g. [info], [warning], etc).
    */
-  // TODO(sigmund): add support for logging exceptions.
-  void log(Level logLevel, String message) {
+  void log(Level logLevel, String message, [exception]) {
     if (isLoggable(logLevel)) {
-      var record = new LogRecord(logLevel, message, fullName);
+      var record = new LogRecord(logLevel, message, fullName, exception);
       if (hierarchicalLoggingEnabled) {
         var target = this;
         while (target != null) {
@@ -170,28 +169,36 @@
   }
 
   /** Log message at level [Level.FINEST]. */
-  void finest(String message) => log(Level.FINEST, message);
+  void finest(String message, [exception]) =>
+      log(Level.FINEST, message, exception);
 
   /** Log message at level [Level.FINER]. */
-  void finer(String message) => log(Level.FINER, message);
+  void finer(String message, [exception]) =>
+      log(Level.FINER, message, exception);
 
   /** Log message at level [Level.FINE]. */
-  void fine(String message) => log(Level.FINE, message);
+  void fine(String message, [exception]) =>
+      log(Level.FINE, message, exception);
 
   /** Log message at level [Level.CONFIG]. */
-  void config(String message) => log(Level.CONFIG, message);
+  void config(String message, [exception]) =>
+      log(Level.CONFIG, message, exception);
 
   /** Log message at level [Level.INFO]. */
-  void info(String message) => log(Level.INFO, message);
+  void info(String message, [exception]) =>
+      log(Level.INFO, message, exception);
 
   /** Log message at level [Level.WARNING]. */
-  void warning(String message) => log(Level.WARNING, message);
+  void warning(String message, [exception]) =>
+      log(Level.WARNING, message, exception);
 
   /** Log message at level [Level.SEVERE]. */
-  void severe(String message) => log(Level.SEVERE, message);
+  void severe(String message, [exception]) =>
+      log(Level.SEVERE, message, exception);
 
   /** Log message at level [Level.SHOUT]. */
-  void shout(String message) => log(Level.SHOUT, message);
+  void shout(String message, [exception]) =>
+      log(Level.SHOUT, message, exception);
 
   Stream<LogRecord> _getStream() {
     if (hierarchicalLoggingEnabled || parent == null) {
@@ -308,14 +315,9 @@
   static int _nextNumber = 0;
 
   /** Associated exception (if any) when recording errors messages. */
-  Exception exception;
+  var exception;
 
-  /** Associated exception message (if any) when recording errors messages. */
-  String exceptionText;
-
-  LogRecord(
-      this.level, this.message, this.loggerName,
-      [time, this.exception, this.exceptionText]) :
-    this.time = (time == null) ? new DateTime.now() : time,
-    this.sequenceNumber = LogRecord._nextNumber++;
+  LogRecord(this.level, this.message, this.loggerName, [this.exception])
+      : time = new DateTime.now(),
+        sequenceNumber = LogRecord._nextNumber++;
 }
diff --git a/pkg/logging/test/logging_test.dart b/pkg/logging/test/logging_test.dart
index 1af342f..a631e8c 100644
--- a/pkg/logging/test/logging_test.dart
+++ b/pkg/logging/test/logging_test.dart
@@ -228,6 +228,49 @@
         'SHOUT: 8']));
     });
 
+    test('logging methods store exception', () {
+      root.level = Level.ALL;
+      var rootMessages = [];
+      root.onRecord.listen((r) {
+        rootMessages.add('${r.level}: ${r.message} ${r.exception}');
+      });
+
+      root.finest('1');
+      root.finer('2');
+      root.fine('3');
+      root.config('4');
+      root.info('5');
+      root.warning('6');
+      root.severe('7');
+      root.shout('8');
+      root.finest('1', 'a');
+      root.finer('2', 'b');
+      root.fine('3', ['c']);
+      root.config('4', 'd');
+      root.info('5', 'e');
+      root.warning('6', 'f');
+      root.severe('7', 'g');
+      root.shout('8', 'h');
+
+      expect(rootMessages, equals([
+        'FINEST: 1 null',
+        'FINER: 2 null',
+        'FINE: 3 null',
+        'CONFIG: 4 null',
+        'INFO: 5 null',
+        'WARNING: 6 null',
+        'SEVERE: 7 null',
+        'SHOUT: 8 null',
+        'FINEST: 1 a',
+        'FINER: 2 b',
+        'FINE: 3 [c]',
+        'CONFIG: 4 d',
+        'INFO: 5 e',
+        'WARNING: 6 f',
+        'SEVERE: 7 g',
+        'SHOUT: 8 h']));
+    });
+
     test('message logging - no hierarchy', () {
       root.level = Level.WARNING;
       var rootMessages = [];
diff --git a/pkg/mdv_observe/lib/src/observable_map.dart b/pkg/mdv_observe/lib/src/observable_map.dart
index ce1e48f..3ce2d82 100644
--- a/pkg/mdv_observe/lib/src/observable_map.dart
+++ b/pkg/mdv_observe/lib/src/observable_map.dart
@@ -94,11 +94,11 @@
 
   bool get isNotEmpty => !isEmpty;
 
-  bool containsValue(V value) => _map.containsValue(value);
+  bool containsValue(Object value) => _map.containsValue(value);
 
-  bool containsKey(K key) => _map.containsKey(key);
+  bool containsKey(Object key) => _map.containsKey(key);
 
-  V operator [](K key) => _map[key];
+  V operator [](Object key) => _map[key];
 
   void operator []=(K key, V value) {
     int len = _map.length;
@@ -124,7 +124,7 @@
     return result;
   }
 
-  V remove(K key) {
+  V remove(Object key) {
     int len = _map.length;
     V result =  _map.remove(key);
     if (hasObservers && len != _map.length) {
diff --git a/pkg/mime/lib/mime.dart b/pkg/mime/lib/mime.dart
new file mode 100644
index 0000000..0943de8
--- /dev/null
+++ b/pkg/mime/lib/mime.dart
@@ -0,0 +1,9 @@
+// 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 mime;
+
+part 'src/mime_type.dart';
+part 'src/extension_map.dart';
+part 'src/magic_number.dart';
diff --git a/pkg/mime/lib/src/extension_map.dart b/pkg/mime/lib/src/extension_map.dart
new file mode 100644
index 0000000..19286bb
--- /dev/null
+++ b/pkg/mime/lib/src/extension_map.dart
@@ -0,0 +1,993 @@
+// 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.
+
+part of mime;
+
+
+// TODO(ajohnsen): Use sorted list and binary search?
+Map<String, String> _defaultExtensionMap = const <String, String>{
+'123':'application/vnd.lotus-1-2-3',
+'3dml':'text/vnd.in3d.3dml',
+'3ds':'image/x-3ds',
+'3g2':'video/3gpp2',
+'3gp':'video/3gpp',
+'7z':'application/x-7z-compressed',
+'aab':'application/x-authorware-bin',
+'aac':'audio/x-aac',
+'aam':'application/x-authorware-map',
+'aas':'application/x-authorware-seg',
+'abw':'application/x-abiword',
+'ac':'application/pkix-attr-cert',
+'acc':'application/vnd.americandynamics.acc',
+'ace':'application/x-ace-compressed',
+'acu':'application/vnd.acucobol',
+'acutc':'application/vnd.acucorp',
+'adp':'audio/adpcm',
+'aep':'application/vnd.audiograph',
+'afm':'application/x-font-type1',
+'afp':'application/vnd.ibm.modcap',
+'ahead':'application/vnd.ahead.space',
+'ai':'application/postscript',
+'aif':'audio/x-aiff',
+'aifc':'audio/x-aiff',
+'aiff':'audio/x-aiff',
+'air':'application/vnd.adobe.air-application-installer-package+zip',
+'ait':'application/vnd.dvb.ait',
+'ami':'application/vnd.amiga.ami',
+'apk':'application/vnd.android.package-archive',
+'appcache':'text/cache-manifest',
+'application':'application/x-ms-application',
+'apr':'application/vnd.lotus-approach',
+'arc':'application/x-freearc',
+'asc':'application/pgp-signature',
+'asf':'video/x-ms-asf',
+'asm':'text/x-asm',
+'aso':'application/vnd.accpac.simply.aso',
+'asx':'video/x-ms-asf',
+'atc':'application/vnd.acucorp',
+'atom':'application/atom+xml',
+'atomcat':'application/atomcat+xml',
+'atomsvc':'application/atomsvc+xml',
+'atx':'application/vnd.antix.game-component',
+'au':'audio/basic',
+'avi':'video/x-msvideo',
+'aw':'application/applixware',
+'azf':'application/vnd.airzip.filesecure.azf',
+'azs':'application/vnd.airzip.filesecure.azs',
+'azw':'application/vnd.amazon.ebook',
+'bat':'application/x-msdownload',
+'bcpio':'application/x-bcpio',
+'bdf':'application/x-font-bdf',
+'bdm':'application/vnd.syncml.dm+wbxml',
+'bed':'application/vnd.realvnc.bed',
+'bh2':'application/vnd.fujitsu.oasysprs',
+'bin':'application/octet-stream',
+'blb':'application/x-blorb',
+'blorb':'application/x-blorb',
+'bmi':'application/vnd.bmi',
+'bmp':'image/bmp',
+'book':'application/vnd.framemaker',
+'box':'application/vnd.previewsystems.box',
+'boz':'application/x-bzip2',
+'bpk':'application/octet-stream',
+'btif':'image/prs.btif',
+'bz':'application/x-bzip',
+'bz2':'application/x-bzip2',
+'c':'text/x-c',
+'c11amc':'application/vnd.cluetrust.cartomobile-config',
+'c11amz':'application/vnd.cluetrust.cartomobile-config-pkg',
+'c4d':'application/vnd.clonk.c4group',
+'c4f':'application/vnd.clonk.c4group',
+'c4g':'application/vnd.clonk.c4group',
+'c4p':'application/vnd.clonk.c4group',
+'c4u':'application/vnd.clonk.c4group',
+'cab':'application/vnd.ms-cab-compressed',
+'caf':'audio/x-caf',
+'cap':'application/vnd.tcpdump.pcap',
+'car':'application/vnd.curl.car',
+'cat':'application/vnd.ms-pki.seccat',
+'cb7':'application/x-cbr',
+'cba':'application/x-cbr',
+'cbr':'application/x-cbr',
+'cbt':'application/x-cbr',
+'cbz':'application/x-cbr',
+'cc':'text/x-c',
+'cct':'application/x-director',
+'ccxml':'application/ccxml+xml',
+'cdbcmsg':'application/vnd.contact.cmsg',
+'cdf':'application/x-netcdf',
+'cdkey':'application/vnd.mediastation.cdkey',
+'cdmia':'application/cdmi-capability',
+'cdmic':'application/cdmi-container',
+'cdmid':'application/cdmi-domain',
+'cdmio':'application/cdmi-object',
+'cdmiq':'application/cdmi-queue',
+'cdx':'chemical/x-cdx',
+'cdxml':'application/vnd.chemdraw+xml',
+'cdy':'application/vnd.cinderella',
+'cer':'application/pkix-cert',
+'cfs':'application/x-cfs-compressed',
+'cgm':'image/cgm',
+'chat':'application/x-chat',
+'chm':'application/vnd.ms-htmlhelp',
+'chrt':'application/vnd.kde.kchart',
+'cif':'chemical/x-cif',
+'cii':'application/vnd.anser-web-certificate-issue-initiation',
+'cil':'application/vnd.ms-artgalry',
+'cla':'application/vnd.claymore',
+'class':'application/java-vm',
+'clkk':'application/vnd.crick.clicker.keyboard',
+'clkp':'application/vnd.crick.clicker.palette',
+'clkt':'application/vnd.crick.clicker.template',
+'clkw':'application/vnd.crick.clicker.wordbank',
+'clkx':'application/vnd.crick.clicker',
+'clp':'application/x-msclip',
+'cmc':'application/vnd.cosmocaller',
+'cmdf':'chemical/x-cmdf',
+'cml':'chemical/x-cml',
+'cmp':'application/vnd.yellowriver-custom-menu',
+'cmx':'image/x-cmx',
+'cod':'application/vnd.rim.cod',
+'com':'application/x-msdownload',
+'conf':'text/plain',
+'cpio':'application/x-cpio',
+'cpp':'text/x-c',
+'cpt':'application/mac-compactpro',
+'crd':'application/x-mscardfile',
+'crl':'application/pkix-crl',
+'crt':'application/x-x509-ca-cert',
+'cryptonote':'application/vnd.rig.cryptonote',
+'csh':'application/x-csh',
+'csml':'chemical/x-csml',
+'csp':'application/vnd.commonspace',
+'css':'text/css',
+'cst':'application/x-director',
+'csv':'text/csv',
+'cu':'application/cu-seeme',
+'curl':'text/vnd.curl',
+'cww':'application/prs.cww',
+'cxt':'application/x-director',
+'cxx':'text/x-c',
+'dae':'model/vnd.collada+xml',
+'daf':'application/vnd.mobius.daf',
+'dart':'application/dart',
+'dataless':'application/vnd.fdsn.seed',
+'davmount':'application/davmount+xml',
+'dbk':'application/docbook+xml',
+'dcr':'application/x-director',
+'dcurl':'text/vnd.curl.dcurl',
+'dd2':'application/vnd.oma.dd2+xml',
+'ddd':'application/vnd.fujixerox.ddd',
+'deb':'application/x-debian-package',
+'def':'text/plain',
+'deploy':'application/octet-stream',
+'der':'application/x-x509-ca-cert',
+'dfac':'application/vnd.dreamfactory',
+'dgc':'application/x-dgc-compressed',
+'dic':'text/x-c',
+'dir':'application/x-director',
+'dis':'application/vnd.mobius.dis',
+'dist':'application/octet-stream',
+'distz':'application/octet-stream',
+'djv':'image/vnd.djvu',
+'djvu':'image/vnd.djvu',
+'dll':'application/x-msdownload',
+'dmg':'application/x-apple-diskimage',
+'dmp':'application/vnd.tcpdump.pcap',
+'dms':'application/octet-stream',
+'dna':'application/vnd.dna',
+'doc':'application/msword',
+'docm':'application/vnd.ms-word.document.macroenabled.12',
+'docx':'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+'dot':'application/msword',
+'dotm':'application/vnd.ms-word.template.macroenabled.12',
+'dotx':'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
+'dp':'application/vnd.osgi.dp',
+'dpg':'application/vnd.dpgraph',
+'dra':'audio/vnd.dra',
+'dsc':'text/prs.lines.tag',
+'dssc':'application/dssc+der',
+'dtb':'application/x-dtbook+xml',
+'dtd':'application/xml-dtd',
+'dts':'audio/vnd.dts',
+'dtshd':'audio/vnd.dts.hd',
+'dump':'application/octet-stream',
+'dvb':'video/vnd.dvb.file',
+'dvi':'application/x-dvi',
+'dwf':'model/vnd.dwf',
+'dwg':'image/vnd.dwg',
+'dxf':'image/vnd.dxf',
+'dxp':'application/vnd.spotfire.dxp',
+'dxr':'application/x-director',
+'ecelp4800':'audio/vnd.nuera.ecelp4800',
+'ecelp7470':'audio/vnd.nuera.ecelp7470',
+'ecelp9600':'audio/vnd.nuera.ecelp9600',
+'ecma':'application/ecmascript',
+'edm':'application/vnd.novadigm.edm',
+'edx':'application/vnd.novadigm.edx',
+'efif':'application/vnd.picsel',
+'ei6':'application/vnd.pg.osasli',
+'elc':'application/octet-stream',
+'emf':'application/x-msmetafile',
+'eml':'message/rfc822',
+'emma':'application/emma+xml',
+'emz':'application/x-msmetafile',
+'eol':'audio/vnd.digital-winds',
+'eot':'application/vnd.ms-fontobject',
+'eps':'application/postscript',
+'epub':'application/epub+zip',
+'es3':'application/vnd.eszigno3+xml',
+'esa':'application/vnd.osgi.subsystem',
+'esf':'application/vnd.epson.esf',
+'et3':'application/vnd.eszigno3+xml',
+'etx':'text/x-setext',
+'eva':'application/x-eva',
+'evy':'application/x-envoy',
+'exe':'application/x-msdownload',
+'exi':'application/exi',
+'ext':'application/vnd.novadigm.ext',
+'ez':'application/andrew-inset',
+'ez2':'application/vnd.ezpix-album',
+'ez3':'application/vnd.ezpix-package',
+'f':'text/x-fortran',
+'f4v':'video/x-f4v',
+'f77':'text/x-fortran',
+'f90':'text/x-fortran',
+'fbs':'image/vnd.fastbidsheet',
+'fcdt':'application/vnd.adobe.formscentral.fcdt',
+'fcs':'application/vnd.isac.fcs',
+'fdf':'application/vnd.fdf',
+'fe_launch':'application/vnd.denovo.fcselayout-link',
+'fg5':'application/vnd.fujitsu.oasysgp',
+'fgd':'application/x-director',
+'fh':'image/x-freehand',
+'fh4':'image/x-freehand',
+'fh5':'image/x-freehand',
+'fh7':'image/x-freehand',
+'fhc':'image/x-freehand',
+'fig':'application/x-xfig',
+'flac':'audio/x-flac',
+'fli':'video/x-fli',
+'flo':'application/vnd.micrografx.flo',
+'flv':'video/x-flv',
+'flw':'application/vnd.kde.kivio',
+'flx':'text/vnd.fmi.flexstor',
+'fly':'text/vnd.fly',
+'fm':'application/vnd.framemaker',
+'fnc':'application/vnd.frogans.fnc',
+'for':'text/x-fortran',
+'fpx':'image/vnd.fpx',
+'frame':'application/vnd.framemaker',
+'fsc':'application/vnd.fsc.weblaunch',
+'fst':'image/vnd.fst',
+'ftc':'application/vnd.fluxtime.clip',
+'fti':'application/vnd.anser-web-funds-transfer-initiation',
+'fvt':'video/vnd.fvt',
+'fxp':'application/vnd.adobe.fxp',
+'fxpl':'application/vnd.adobe.fxp',
+'fzs':'application/vnd.fuzzysheet',
+'g2w':'application/vnd.geoplan',
+'g3':'image/g3fax',
+'g3w':'application/vnd.geospace',
+'gac':'application/vnd.groove-account',
+'gam':'application/x-tads',
+'gbr':'application/rpki-ghostbusters',
+'gca':'application/x-gca-compressed',
+'gdl':'model/vnd.gdl',
+'geo':'application/vnd.dynageo',
+'gex':'application/vnd.geometry-explorer',
+'ggb':'application/vnd.geogebra.file',
+'ggt':'application/vnd.geogebra.tool',
+'ghf':'application/vnd.groove-help',
+'gif':'image/gif',
+'gim':'application/vnd.groove-identity-message',
+'gml':'application/gml+xml',
+'gmx':'application/vnd.gmx',
+'gnumeric':'application/x-gnumeric',
+'gph':'application/vnd.flographit',
+'gpx':'application/gpx+xml',
+'gqf':'application/vnd.grafeq',
+'gqs':'application/vnd.grafeq',
+'gram':'application/srgs',
+'gramps':'application/x-gramps-xml',
+'gre':'application/vnd.geometry-explorer',
+'grv':'application/vnd.groove-injector',
+'grxml':'application/srgs+xml',
+'gsf':'application/x-font-ghostscript',
+'gtar':'application/x-gtar',
+'gtm':'application/vnd.groove-tool-message',
+'gtw':'model/vnd.gtw',
+'gv':'text/vnd.graphviz',
+'gxf':'application/gxf',
+'gxt':'application/vnd.geonext',
+'h':'text/x-c',
+'h261':'video/h261',
+'h263':'video/h263',
+'h264':'video/h264',
+'hal':'application/vnd.hal+xml',
+'hbci':'application/vnd.hbci',
+'hdf':'application/x-hdf',
+'hh':'text/x-c',
+'hlp':'application/winhlp',
+'hpgl':'application/vnd.hp-hpgl',
+'hpid':'application/vnd.hp-hpid',
+'hps':'application/vnd.hp-hps',
+'hqx':'application/mac-binhex40',
+'htke':'application/vnd.kenameaapp',
+'htm':'text/html',
+'html':'text/html',
+'hvd':'application/vnd.yamaha.hv-dic',
+'hvp':'application/vnd.yamaha.hv-voice',
+'hvs':'application/vnd.yamaha.hv-script',
+'i2g':'application/vnd.intergeo',
+'icc':'application/vnd.iccprofile',
+'ice':'x-conference/x-cooltalk',
+'icm':'application/vnd.iccprofile',
+'ico':'image/x-icon',
+'ics':'text/calendar',
+'ief':'image/ief',
+'ifb':'text/calendar',
+'ifm':'application/vnd.shana.informed.formdata',
+'iges':'model/iges',
+'igl':'application/vnd.igloader',
+'igm':'application/vnd.insors.igm',
+'igs':'model/iges',
+'igx':'application/vnd.micrografx.igx',
+'iif':'application/vnd.shana.informed.interchange',
+'imp':'application/vnd.accpac.simply.imp',
+'ims':'application/vnd.ms-ims',
+'in':'text/plain',
+'ink':'application/inkml+xml',
+'inkml':'application/inkml+xml',
+'install':'application/x-install-instructions',
+'iota':'application/vnd.astraea-software.iota',
+'ipfix':'application/ipfix',
+'ipk':'application/vnd.shana.informed.package',
+'irm':'application/vnd.ibm.rights-management',
+'irp':'application/vnd.irepository.package+xml',
+'iso':'application/x-iso9660-image',
+'itp':'application/vnd.shana.informed.formtemplate',
+'ivp':'application/vnd.immervision-ivp',
+'ivu':'application/vnd.immervision-ivu',
+'jad':'text/vnd.sun.j2me.app-descriptor',
+'jam':'application/vnd.jam',
+'jar':'application/java-archive',
+'java':'text/x-java-source',
+'jisp':'application/vnd.jisp',
+'jlt':'application/vnd.hp-jlyt',
+'jnlp':'application/x-java-jnlp-file',
+'joda':'application/vnd.joost.joda-archive',
+'jpe':'image/jpeg',
+'jpeg':'image/jpeg',
+'jpg':'image/jpeg',
+'jpgm':'video/jpm',
+'jpgv':'video/jpeg',
+'jpm':'video/jpm',
+'js':'application/javascript',
+'json':'application/json',
+'jsonml':'application/jsonml+json',
+'kar':'audio/midi',
+'karbon':'application/vnd.kde.karbon',
+'kfo':'application/vnd.kde.kformula',
+'kia':'application/vnd.kidspiration',
+'kml':'application/vnd.google-earth.kml+xml',
+'kmz':'application/vnd.google-earth.kmz',
+'kne':'application/vnd.kinar',
+'knp':'application/vnd.kinar',
+'kon':'application/vnd.kde.kontour',
+'kpr':'application/vnd.kde.kpresenter',
+'kpt':'application/vnd.kde.kpresenter',
+'kpxx':'application/vnd.ds-keypoint',
+'ksp':'application/vnd.kde.kspread',
+'ktr':'application/vnd.kahootz',
+'ktx':'image/ktx',
+'ktz':'application/vnd.kahootz',
+'kwd':'application/vnd.kde.kword',
+'kwt':'application/vnd.kde.kword',
+'lasxml':'application/vnd.las.las+xml',
+'latex':'application/x-latex',
+'lbd':'application/vnd.llamagraphics.life-balance.desktop',
+'lbe':'application/vnd.llamagraphics.life-balance.exchange+xml',
+'les':'application/vnd.hhe.lesson-player',
+'lha':'application/x-lzh-compressed',
+'link66':'application/vnd.route66.link66+xml',
+'list':'text/plain',
+'list3820':'application/vnd.ibm.modcap',
+'listafp':'application/vnd.ibm.modcap',
+'lnk':'application/x-ms-shortcut',
+'log':'text/plain',
+'lostxml':'application/lost+xml',
+'lrf':'application/octet-stream',
+'lrm':'application/vnd.ms-lrm',
+'ltf':'application/vnd.frogans.ltf',
+'lvp':'audio/vnd.lucent.voice',
+'lwp':'application/vnd.lotus-wordpro',
+'lzh':'application/x-lzh-compressed',
+'m13':'application/x-msmediaview',
+'m14':'application/x-msmediaview',
+'m1v':'video/mpeg',
+'m21':'application/mp21',
+'m2a':'audio/mpeg',
+'m2v':'video/mpeg',
+'m3a':'audio/mpeg',
+'m3u':'audio/x-mpegurl',
+'m3u8':'application/vnd.apple.mpegurl',
+'m4u':'video/vnd.mpegurl',
+'m4v':'video/x-m4v',
+'ma':'application/mathematica',
+'mads':'application/mads+xml',
+'mag':'application/vnd.ecowin.chart',
+'maker':'application/vnd.framemaker',
+'man':'text/troff',
+'mar':'application/octet-stream',
+'mathml':'application/mathml+xml',
+'mb':'application/mathematica',
+'mbk':'application/vnd.mobius.mbk',
+'mbox':'application/mbox',
+'mc1':'application/vnd.medcalcdata',
+'mcd':'application/vnd.mcd',
+'mcurl':'text/vnd.curl.mcurl',
+'mdb':'application/x-msaccess',
+'mdi':'image/vnd.ms-modi',
+'me':'text/troff',
+'mesh':'model/mesh',
+'meta4':'application/metalink4+xml',
+'metalink':'application/metalink+xml',
+'mets':'application/mets+xml',
+'mfm':'application/vnd.mfmp',
+'mft':'application/rpki-manifest',
+'mgp':'application/vnd.osgeo.mapguide.package',
+'mgz':'application/vnd.proteus.magazine',
+'mid':'audio/midi',
+'midi':'audio/midi',
+'mie':'application/x-mie',
+'mif':'application/vnd.mif',
+'mime':'message/rfc822',
+'mj2':'video/mj2',
+'mjp2':'video/mj2',
+'mk3d':'video/x-matroska',
+'mka':'audio/x-matroska',
+'mks':'video/x-matroska',
+'mkv':'video/x-matroska',
+'mlp':'application/vnd.dolby.mlp',
+'mmd':'application/vnd.chipnuts.karaoke-mmd',
+'mmf':'application/vnd.smaf',
+'mmr':'image/vnd.fujixerox.edmics-mmr',
+'mng':'video/x-mng',
+'mny':'application/x-msmoney',
+'mobi':'application/x-mobipocket-ebook',
+'mods':'application/mods+xml',
+'mov':'video/quicktime',
+'movie':'video/x-sgi-movie',
+'mp2':'audio/mpeg',
+'mp21':'application/mp21',
+'mp2a':'audio/mpeg',
+'mp3':'audio/mpeg',
+'mp4':'video/mp4',
+'mp4a':'audio/mp4',
+'mp4s':'application/mp4',
+'mp4v':'video/mp4',
+'mpc':'application/vnd.mophun.certificate',
+'mpe':'video/mpeg',
+'mpeg':'video/mpeg',
+'mpg':'video/mpeg',
+'mpg4':'video/mp4',
+'mpga':'audio/mpeg',
+'mpkg':'application/vnd.apple.installer+xml',
+'mpm':'application/vnd.blueice.multipass',
+'mpn':'application/vnd.mophun.application',
+'mpp':'application/vnd.ms-project',
+'mpt':'application/vnd.ms-project',
+'mpy':'application/vnd.ibm.minipay',
+'mqy':'application/vnd.mobius.mqy',
+'mrc':'application/marc',
+'mrcx':'application/marcxml+xml',
+'ms':'text/troff',
+'mscml':'application/mediaservercontrol+xml',
+'mseed':'application/vnd.fdsn.mseed',
+'mseq':'application/vnd.mseq',
+'msf':'application/vnd.epson.msf',
+'msh':'model/mesh',
+'msi':'application/x-msdownload',
+'msl':'application/vnd.mobius.msl',
+'msty':'application/vnd.muvee.style',
+'mts':'model/vnd.mts',
+'mus':'application/vnd.musician',
+'musicxml':'application/vnd.recordare.musicxml+xml',
+'mvb':'application/x-msmediaview',
+'mwf':'application/vnd.mfer',
+'mxf':'application/mxf',
+'mxl':'application/vnd.recordare.musicxml',
+'mxml':'application/xv+xml',
+'mxs':'application/vnd.triscape.mxs',
+'mxu':'video/vnd.mpegurl',
+'n-gage':'application/vnd.nokia.n-gage.symbian.install',
+'n3':'text/n3',
+'nb':'application/mathematica',
+'nbp':'application/vnd.wolfram.player',
+'nc':'application/x-netcdf',
+'ncx':'application/x-dtbncx+xml',
+'nfo':'text/x-nfo',
+'ngdat':'application/vnd.nokia.n-gage.data',
+'nitf':'application/vnd.nitf',
+'nlu':'application/vnd.neurolanguage.nlu',
+'nml':'application/vnd.enliven',
+'nnd':'application/vnd.noblenet-directory',
+'nns':'application/vnd.noblenet-sealer',
+'nnw':'application/vnd.noblenet-web',
+'npx':'image/vnd.net-fpx',
+'nsc':'application/x-conference',
+'nsf':'application/vnd.lotus-notes',
+'ntf':'application/vnd.nitf',
+'nzb':'application/x-nzb',
+'oa2':'application/vnd.fujitsu.oasys2',
+'oa3':'application/vnd.fujitsu.oasys3',
+'oas':'application/vnd.fujitsu.oasys',
+'obd':'application/x-msbinder',
+'obj':'application/x-tgif',
+'oda':'application/oda',
+'odb':'application/vnd.oasis.opendocument.database',
+'odc':'application/vnd.oasis.opendocument.chart',
+'odf':'application/vnd.oasis.opendocument.formula',
+'odft':'application/vnd.oasis.opendocument.formula-template',
+'odg':'application/vnd.oasis.opendocument.graphics',
+'odi':'application/vnd.oasis.opendocument.image',
+'odm':'application/vnd.oasis.opendocument.text-master',
+'odp':'application/vnd.oasis.opendocument.presentation',
+'ods':'application/vnd.oasis.opendocument.spreadsheet',
+'odt':'application/vnd.oasis.opendocument.text',
+'oga':'audio/ogg',
+'ogg':'audio/ogg',
+'ogv':'video/ogg',
+'ogx':'application/ogg',
+'omdoc':'application/omdoc+xml',
+'onepkg':'application/onenote',
+'onetmp':'application/onenote',
+'onetoc':'application/onenote',
+'onetoc2':'application/onenote',
+'opf':'application/oebps-package+xml',
+'opml':'text/x-opml',
+'oprc':'application/vnd.palm',
+'org':'application/vnd.lotus-organizer',
+'osf':'application/vnd.yamaha.openscoreformat',
+'osfpvg':'application/vnd.yamaha.openscoreformat.osfpvg+xml',
+'otc':'application/vnd.oasis.opendocument.chart-template',
+'otf':'application/x-font-otf',
+'otg':'application/vnd.oasis.opendocument.graphics-template',
+'oth':'application/vnd.oasis.opendocument.text-web',
+'oti':'application/vnd.oasis.opendocument.image-template',
+'otp':'application/vnd.oasis.opendocument.presentation-template',
+'ots':'application/vnd.oasis.opendocument.spreadsheet-template',
+'ott':'application/vnd.oasis.opendocument.text-template',
+'oxps':'application/oxps',
+'oxt':'application/vnd.openofficeorg.extension',
+'p':'text/x-pascal',
+'p10':'application/pkcs10',
+'p12':'application/x-pkcs12',
+'p7b':'application/x-pkcs7-certificates',
+'p7c':'application/pkcs7-mime',
+'p7m':'application/pkcs7-mime',
+'p7r':'application/x-pkcs7-certreqresp',
+'p7s':'application/pkcs7-signature',
+'p8':'application/pkcs8',
+'pas':'text/x-pascal',
+'paw':'application/vnd.pawaafile',
+'pbd':'application/vnd.powerbuilder6',
+'pbm':'image/x-portable-bitmap',
+'pcap':'application/vnd.tcpdump.pcap',
+'pcf':'application/x-font-pcf',
+'pcl':'application/vnd.hp-pcl',
+'pclxl':'application/vnd.hp-pclxl',
+'pct':'image/x-pict',
+'pcurl':'application/vnd.curl.pcurl',
+'pcx':'image/x-pcx',
+'pdb':'application/vnd.palm',
+'pdf':'application/pdf',
+'pfa':'application/x-font-type1',
+'pfb':'application/x-font-type1',
+'pfm':'application/x-font-type1',
+'pfr':'application/font-tdpfr',
+'pfx':'application/x-pkcs12',
+'pgm':'image/x-portable-graymap',
+'pgn':'application/x-chess-pgn',
+'pgp':'application/pgp-encrypted',
+'pic':'image/x-pict',
+'pkg':'application/octet-stream',
+'pki':'application/pkixcmp',
+'pkipath':'application/pkix-pkipath',
+'plb':'application/vnd.3gpp.pic-bw-large',
+'plc':'application/vnd.mobius.plc',
+'plf':'application/vnd.pocketlearn',
+'pls':'application/pls+xml',
+'pml':'application/vnd.ctc-posml',
+'png':'image/png',
+'pnm':'image/x-portable-anymap',
+'portpkg':'application/vnd.macports.portpkg',
+'pot':'application/vnd.ms-powerpoint',
+'potm':'application/vnd.ms-powerpoint.template.macroenabled.12',
+'potx':'application/vnd.openxmlformats-officedocument.presentationml.template',
+'ppam':'application/vnd.ms-powerpoint.addin.macroenabled.12',
+'ppd':'application/vnd.cups-ppd',
+'ppm':'image/x-portable-pixmap',
+'pps':'application/vnd.ms-powerpoint',
+'ppsm':'application/vnd.ms-powerpoint.slideshow.macroenabled.12',
+'ppsx':'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
+'ppt':'application/vnd.ms-powerpoint',
+'pptm':'application/vnd.ms-powerpoint.presentation.macroenabled.12',
+'pptx':'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+'pqa':'application/vnd.palm',
+'prc':'application/x-mobipocket-ebook',
+'pre':'application/vnd.lotus-freelance',
+'prf':'application/pics-rules',
+'ps':'application/postscript',
+'psb':'application/vnd.3gpp.pic-bw-small',
+'psd':'image/vnd.adobe.photoshop',
+'psf':'application/x-font-linux-psf',
+'pskcxml':'application/pskc+xml',
+'ptid':'application/vnd.pvi.ptid1',
+'pub':'application/x-mspublisher',
+'pvb':'application/vnd.3gpp.pic-bw-var',
+'pwn':'application/vnd.3m.post-it-notes',
+'pya':'audio/vnd.ms-playready.media.pya',
+'pyv':'video/vnd.ms-playready.media.pyv',
+'qam':'application/vnd.epson.quickanime',
+'qbo':'application/vnd.intu.qbo',
+'qfx':'application/vnd.intu.qfx',
+'qps':'application/vnd.publishare-delta-tree',
+'qt':'video/quicktime',
+'qwd':'application/vnd.quark.quarkxpress',
+'qwt':'application/vnd.quark.quarkxpress',
+'qxb':'application/vnd.quark.quarkxpress',
+'qxd':'application/vnd.quark.quarkxpress',
+'qxl':'application/vnd.quark.quarkxpress',
+'qxt':'application/vnd.quark.quarkxpress',
+'ra':'audio/x-pn-realaudio',
+'ram':'audio/x-pn-realaudio',
+'rar':'application/x-rar-compressed',
+'ras':'image/x-cmu-raster',
+'rcprofile':'application/vnd.ipunplugged.rcprofile',
+'rdf':'application/rdf+xml',
+'rdz':'application/vnd.data-vision.rdz',
+'rep':'application/vnd.businessobjects',
+'res':'application/x-dtbresource+xml',
+'rgb':'image/x-rgb',
+'rif':'application/reginfo+xml',
+'rip':'audio/vnd.rip',
+'ris':'application/x-research-info-systems',
+'rl':'application/resource-lists+xml',
+'rlc':'image/vnd.fujixerox.edmics-rlc',
+'rld':'application/resource-lists-diff+xml',
+'rm':'application/vnd.rn-realmedia',
+'rmi':'audio/midi',
+'rmp':'audio/x-pn-realaudio-plugin',
+'rms':'application/vnd.jcp.javame.midlet-rms',
+'rmvb':'application/vnd.rn-realmedia-vbr',
+'rnc':'application/relax-ng-compact-syntax',
+'roa':'application/rpki-roa',
+'roff':'text/troff',
+'rp9':'application/vnd.cloanto.rp9',
+'rpss':'application/vnd.nokia.radio-presets',
+'rpst':'application/vnd.nokia.radio-preset',
+'rq':'application/sparql-query',
+'rs':'application/rls-services+xml',
+'rsd':'application/rsd+xml',
+'rss':'application/rss+xml',
+'rtf':'application/rtf',
+'rtx':'text/richtext',
+'s':'text/x-asm',
+'s3m':'audio/s3m',
+'saf':'application/vnd.yamaha.smaf-audio',
+'sbml':'application/sbml+xml',
+'sc':'application/vnd.ibm.secure-container',
+'scd':'application/x-msschedule',
+'scm':'application/vnd.lotus-screencam',
+'scq':'application/scvp-cv-request',
+'scs':'application/scvp-cv-response',
+'scurl':'text/vnd.curl.scurl',
+'sda':'application/vnd.stardivision.draw',
+'sdc':'application/vnd.stardivision.calc',
+'sdd':'application/vnd.stardivision.impress',
+'sdkd':'application/vnd.solent.sdkm+xml',
+'sdkm':'application/vnd.solent.sdkm+xml',
+'sdp':'application/sdp',
+'sdw':'application/vnd.stardivision.writer',
+'see':'application/vnd.seemail',
+'seed':'application/vnd.fdsn.seed',
+'sema':'application/vnd.sema',
+'semd':'application/vnd.semd',
+'semf':'application/vnd.semf',
+'ser':'application/java-serialized-object',
+'setpay':'application/set-payment-initiation',
+'setreg':'application/set-registration-initiation',
+'sfd-hdstx':'application/vnd.hydrostatix.sof-data',
+'sfs':'application/vnd.spotfire.sfs',
+'sfv':'text/x-sfv',
+'sgi':'image/sgi',
+'sgl':'application/vnd.stardivision.writer-global',
+'sgm':'text/sgml',
+'sgml':'text/sgml',
+'sh':'application/x-sh',
+'shar':'application/x-shar',
+'shf':'application/shf+xml',
+'sid':'image/x-mrsid-image',
+'sig':'application/pgp-signature',
+'sil':'audio/silk',
+'silo':'model/mesh',
+'sis':'application/vnd.symbian.install',
+'sisx':'application/vnd.symbian.install',
+'sit':'application/x-stuffit',
+'sitx':'application/x-stuffitx',
+'skd':'application/vnd.koan',
+'skm':'application/vnd.koan',
+'skp':'application/vnd.koan',
+'skt':'application/vnd.koan',
+'sldm':'application/vnd.ms-powerpoint.slide.macroenabled.12',
+'sldx':'application/vnd.openxmlformats-officedocument.presentationml.slide',
+'slt':'application/vnd.epson.salt',
+'sm':'application/vnd.stepmania.stepchart',
+'smf':'application/vnd.stardivision.math',
+'smi':'application/smil+xml',
+'smil':'application/smil+xml',
+'smv':'video/x-smv',
+'smzip':'application/vnd.stepmania.package',
+'snd':'audio/basic',
+'snf':'application/x-font-snf',
+'so':'application/octet-stream',
+'spc':'application/x-pkcs7-certificates',
+'spf':'application/vnd.yamaha.smaf-phrase',
+'spl':'application/x-futuresplash',
+'spot':'text/vnd.in3d.spot',
+'spp':'application/scvp-vp-response',
+'spq':'application/scvp-vp-request',
+'spx':'audio/ogg',
+'sql':'application/x-sql',
+'src':'application/x-wais-source',
+'srt':'application/x-subrip',
+'sru':'application/sru+xml',
+'srx':'application/sparql-results+xml',
+'ssdl':'application/ssdl+xml',
+'sse':'application/vnd.kodak-descriptor',
+'ssf':'application/vnd.epson.ssf',
+'ssml':'application/ssml+xml',
+'st':'application/vnd.sailingtracker.track',
+'stc':'application/vnd.sun.xml.calc.template',
+'std':'application/vnd.sun.xml.draw.template',
+'stf':'application/vnd.wt.stf',
+'sti':'application/vnd.sun.xml.impress.template',
+'stk':'application/hyperstudio',
+'stl':'application/vnd.ms-pki.stl',
+'str':'application/vnd.pg.format',
+'stw':'application/vnd.sun.xml.writer.template',
+'sub':'image/vnd.dvb.subtitle',
+'sub':'text/vnd.dvb.subtitle',
+'sus':'application/vnd.sus-calendar',
+'susp':'application/vnd.sus-calendar',
+'sv4cpio':'application/x-sv4cpio',
+'sv4crc':'application/x-sv4crc',
+'svc':'application/vnd.dvb.service',
+'svd':'application/vnd.svd',
+'svg':'image/svg+xml',
+'svgz':'image/svg+xml',
+'swa':'application/x-director',
+'swf':'application/x-shockwave-flash',
+'swi':'application/vnd.aristanetworks.swi',
+'sxc':'application/vnd.sun.xml.calc',
+'sxd':'application/vnd.sun.xml.draw',
+'sxg':'application/vnd.sun.xml.writer.global',
+'sxi':'application/vnd.sun.xml.impress',
+'sxm':'application/vnd.sun.xml.math',
+'sxw':'application/vnd.sun.xml.writer',
+'t':'text/troff',
+'t3':'application/x-t3vm-image',
+'taglet':'application/vnd.mynfc',
+'tao':'application/vnd.tao.intent-module-archive',
+'tar':'application/x-tar',
+'tcap':'application/vnd.3gpp2.tcap',
+'tcl':'application/x-tcl',
+'teacher':'application/vnd.smart.teacher',
+'tei':'application/tei+xml',
+'teicorpus':'application/tei+xml',
+'tex':'application/x-tex',
+'texi':'application/x-texinfo',
+'texinfo':'application/x-texinfo',
+'text':'text/plain',
+'tfi':'application/thraud+xml',
+'tfm':'application/x-tex-tfm',
+'tga':'image/x-tga',
+'thmx':'application/vnd.ms-officetheme',
+'tif':'image/tiff',
+'tiff':'image/tiff',
+'tmo':'application/vnd.tmobile-livetv',
+'torrent':'application/x-bittorrent',
+'tpl':'application/vnd.groove-tool-template',
+'tpt':'application/vnd.trid.tpt',
+'tr':'text/troff',
+'tra':'application/vnd.trueapp',
+'trm':'application/x-msterminal',
+'tsd':'application/timestamped-data',
+'tsv':'text/tab-separated-values',
+'ttc':'application/x-font-ttf',
+'ttf':'application/x-font-ttf',
+'ttl':'text/turtle',
+'twd':'application/vnd.simtech-mindmapper',
+'twds':'application/vnd.simtech-mindmapper',
+'txd':'application/vnd.genomatix.tuxedo',
+'txf':'application/vnd.mobius.txf',
+'txt':'text/plain',
+'u32':'application/x-authorware-bin',
+'udeb':'application/x-debian-package',
+'ufd':'application/vnd.ufdl',
+'ufdl':'application/vnd.ufdl',
+'ulx':'application/x-glulx',
+'umj':'application/vnd.umajin',
+'unityweb':'application/vnd.unity',
+'uoml':'application/vnd.uoml+xml',
+'uri':'text/uri-list',
+'uris':'text/uri-list',
+'urls':'text/uri-list',
+'ustar':'application/x-ustar',
+'utz':'application/vnd.uiq.theme',
+'uu':'text/x-uuencode',
+'uva':'audio/vnd.dece.audio',
+'uvd':'application/vnd.dece.data',
+'uvf':'application/vnd.dece.data',
+'uvg':'image/vnd.dece.graphic',
+'uvh':'video/vnd.dece.hd',
+'uvi':'image/vnd.dece.graphic',
+'uvm':'video/vnd.dece.mobile',
+'uvp':'video/vnd.dece.pd',
+'uvs':'video/vnd.dece.sd',
+'uvt':'application/vnd.dece.ttml+xml',
+'uvu':'video/vnd.uvvu.mp4',
+'uvv':'video/vnd.dece.video',
+'uvva':'audio/vnd.dece.audio',
+'uvvd':'application/vnd.dece.data',
+'uvvf':'application/vnd.dece.data',
+'uvvg':'image/vnd.dece.graphic',
+'uvvh':'video/vnd.dece.hd',
+'uvvi':'image/vnd.dece.graphic',
+'uvvm':'video/vnd.dece.mobile',
+'uvvp':'video/vnd.dece.pd',
+'uvvs':'video/vnd.dece.sd',
+'uvvt':'application/vnd.dece.ttml+xml',
+'uvvu':'video/vnd.uvvu.mp4',
+'uvvv':'video/vnd.dece.video',
+'uvvx':'application/vnd.dece.unspecified',
+'uvvz':'application/vnd.dece.zip',
+'uvx':'application/vnd.dece.unspecified',
+'uvz':'application/vnd.dece.zip',
+'vcard':'text/vcard',
+'vcd':'application/x-cdlink',
+'vcf':'text/x-vcard',
+'vcg':'application/vnd.groove-vcard',
+'vcs':'text/x-vcalendar',
+'vcx':'application/vnd.vcx',
+'vis':'application/vnd.visionary',
+'viv':'video/vnd.vivo',
+'vob':'video/x-ms-vob',
+'vor':'application/vnd.stardivision.writer',
+'vox':'application/x-authorware-bin',
+'vrml':'model/vrml',
+'vsd':'application/vnd.visio',
+'vsf':'application/vnd.vsf',
+'vss':'application/vnd.visio',
+'vst':'application/vnd.visio',
+'vsw':'application/vnd.visio',
+'vtu':'model/vnd.vtu',
+'vxml':'application/voicexml+xml',
+'w3d':'application/x-director',
+'wad':'application/x-doom',
+'wav':'audio/x-wav',
+'wax':'audio/x-ms-wax',
+'wbmp':'image/vnd.wap.wbmp',
+'wbs':'application/vnd.criticaltools.wbs+xml',
+'wbxml':'application/vnd.wap.wbxml',
+'wcm':'application/vnd.ms-works',
+'wdb':'application/vnd.ms-works',
+'wdp':'image/vnd.ms-photo',
+'weba':'audio/webm',
+'webm':'video/webm',
+'webp':'image/webp',
+'wg':'application/vnd.pmi.widget',
+'wgt':'application/widget',
+'wks':'application/vnd.ms-works',
+'wm':'video/x-ms-wm',
+'wma':'audio/x-ms-wma',
+'wmd':'application/x-ms-wmd',
+'wmf':'application/x-msmetafile',
+'wml':'text/vnd.wap.wml',
+'wmlc':'application/vnd.wap.wmlc',
+'wmls':'text/vnd.wap.wmlscript',
+'wmlsc':'application/vnd.wap.wmlscriptc',
+'wmv':'video/x-ms-wmv',
+'wmx':'video/x-ms-wmx',
+'wmz':'application/x-ms-wmz',
+'wmz':'application/x-msmetafile',
+'woff':'application/x-font-woff',
+'wpd':'application/vnd.wordperfect',
+'wpl':'application/vnd.ms-wpl',
+'wps':'application/vnd.ms-works',
+'wqd':'application/vnd.wqd',
+'wri':'application/x-mswrite',
+'wrl':'model/vrml',
+'wsdl':'application/wsdl+xml',
+'wspolicy':'application/wspolicy+xml',
+'wtb':'application/vnd.webturbo',
+'wvx':'video/x-ms-wvx',
+'x32':'application/x-authorware-bin',
+'x3d':'model/x3d+xml',
+'x3db':'model/x3d+binary',
+'x3dbz':'model/x3d+binary',
+'x3dv':'model/x3d+vrml',
+'x3dvz':'model/x3d+vrml',
+'x3dz':'model/x3d+xml',
+'xaml':'application/xaml+xml',
+'xap':'application/x-silverlight-app',
+'xar':'application/vnd.xara',
+'xbap':'application/x-ms-xbap',
+'xbd':'application/vnd.fujixerox.docuworks.binder',
+'xbm':'image/x-xbitmap',
+'xdf':'application/xcap-diff+xml',
+'xdm':'application/vnd.syncml.dm+xml',
+'xdp':'application/vnd.adobe.xdp+xml',
+'xdssc':'application/dssc+xml',
+'xdw':'application/vnd.fujixerox.docuworks',
+'xenc':'application/xenc+xml',
+'xer':'application/patch-ops-error+xml',
+'xfdf':'application/vnd.adobe.xfdf',
+'xfdl':'application/vnd.xfdl',
+'xht':'application/xhtml+xml',
+'xhtml':'application/xhtml+xml',
+'xhvml':'application/xv+xml',
+'xif':'image/vnd.xiff',
+'xla':'application/vnd.ms-excel',
+'xlam':'application/vnd.ms-excel.addin.macroenabled.12',
+'xlc':'application/vnd.ms-excel',
+'xlf':'application/x-xliff+xml',
+'xlm':'application/vnd.ms-excel',
+'xls':'application/vnd.ms-excel',
+'xlsb':'application/vnd.ms-excel.sheet.binary.macroenabled.12',
+'xlsm':'application/vnd.ms-excel.sheet.macroenabled.12',
+'xlsx':'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+'xlt':'application/vnd.ms-excel',
+'xltm':'application/vnd.ms-excel.template.macroenabled.12',
+'xltx':'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
+'xlw':'application/vnd.ms-excel',
+'xm':'audio/xm',
+'xml':'application/xml',
+'xo':'application/vnd.olpc-sugar',
+'xop':'application/xop+xml',
+'xpi':'application/x-xpinstall',
+'xpl':'application/xproc+xml',
+'xpm':'image/x-xpixmap',
+'xpr':'application/vnd.is-xpr',
+'xps':'application/vnd.ms-xpsdocument',
+'xpw':'application/vnd.intercon.formnet',
+'xpx':'application/vnd.intercon.formnet',
+'xsl':'application/xml',
+'xslt':'application/xslt+xml',
+'xsm':'application/vnd.syncml+xml',
+'xspf':'application/xspf+xml',
+'xul':'application/vnd.mozilla.xul+xml',
+'xvm':'application/xv+xml',
+'xvml':'application/xv+xml',
+'xwd':'image/x-xwindowdump',
+'xyz':'chemical/x-xyz',
+'xz':'application/x-xz',
+'yang':'application/yang',
+'yin':'application/yin+xml',
+'z1':'application/x-zmachine',
+'z2':'application/x-zmachine',
+'z3':'application/x-zmachine',
+'z4':'application/x-zmachine',
+'z5':'application/x-zmachine',
+'z6':'application/x-zmachine',
+'z7':'application/x-zmachine',
+'z8':'application/x-zmachine',
+'zaz':'application/vnd.zzazz.deck+xml',
+'zip':'application/zip',
+'zir':'application/vnd.zul',
+'zirz':'application/vnd.zul',
+'zmm':'application/vnd.handheld-entertainment+xml',
+};
diff --git a/pkg/mime/lib/src/magic_number.dart b/pkg/mime/lib/src/magic_number.dart
new file mode 100644
index 0000000..451a093
--- /dev/null
+++ b/pkg/mime/lib/src/magic_number.dart
@@ -0,0 +1,49 @@
+// 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.
+
+part of mime;
+
+
+class _MagicNumber {
+  final String mimeType;
+  final List<int> numbers;
+  final List<int> mask;
+
+  const _MagicNumber(this.mimeType, this.numbers, {this.mask});
+
+  bool matches(List<int> header) {
+    if (header.length < numbers.length) return false;
+
+    for (int i = 0; i < numbers.length; i++) {
+      if (mask != null) {
+        if ((mask[i] & numbers[i]) != (mask[i] & header[i])) return false;
+      } else {
+        if (numbers[i] != header[i]) return false;
+      }
+    }
+
+    return true;
+  }
+
+}
+
+int _defaultMagicNumbersMaxLength = 16;
+
+List<_MagicNumber> _defaultMagicNumbers = const [
+const _MagicNumber('application/pdf', const [0x25, 0x50, 0x44, 0x46]),
+const _MagicNumber('application/postscript', const [0x25, 0x51]),
+const _MagicNumber('image/gif', const [0x47, 0x49, 0x46, 0x38, 0x37, 0x61]),
+const _MagicNumber('image/gif', const [0x47, 0x49, 0x46, 0x38, 0x39, 0x61]),
+const _MagicNumber('image/jpeg', const [0xFF, 0xD8]),
+const _MagicNumber('image/png',
+                   const [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]),
+const _MagicNumber('image/tiff', const [0x49, 0x49, 0x2A, 0x00]),
+const _MagicNumber('image/tiff', const [0x4D, 0x4D, 0x00, 0x2A]),
+const _MagicNumber('video/mp4',
+                   const [0x00, 0x00, 0x00, 0x00, 0x66, 0x74,
+                          0x79, 0x70, 0x33, 0x67, 0x70, 0x35],
+                   mask: const [0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
+                                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
+];
+
diff --git a/pkg/mime/lib/src/mime_type.dart b/pkg/mime/lib/src/mime_type.dart
new file mode 100644
index 0000000..cd08cdf
--- /dev/null
+++ b/pkg/mime/lib/src/mime_type.dart
@@ -0,0 +1,129 @@
+// 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.
+
+part of mime;
+
+
+MimeTypeResolver _globalResolver = new MimeTypeResolver();
+
+/**
+ * The maximum number of bytes needed, to match all default magic-numbers.
+ */
+int get defaultMagicNumbersMaxLength => _defaultMagicNumbersMaxLength;
+
+/**
+ * Extract the extension from [path] and use that for MIME-type lookup, using
+ * the default extension map.
+ *
+ * If no matching MIME-type was found, `null` is returned.
+ *
+ * If [headerBytes] is present, a match for known magic-numbers will be
+ * performed first. This allows the correct mime-type to be found, even though
+ * a file have been saved using the wrong file-name extension. If less than
+ * [defaultMagicNumbersMaxLength] bytes was provided, some magic-numbers won't
+ * be matched against.
+ */
+String lookupMimeType(String path,
+                      {List<int> headerBytes})
+    => _globalResolver.lookup(path, headerBytes: headerBytes);
+
+
+/**
+ * MIME-type resolver class, used to customize the lookup of mime-types.
+ */
+class MimeTypeResolver {
+  final Map<String, String> _extensionMap = {};
+  final List<_MagicNumber> _magicNumbers = [];
+  bool _useDefault;
+  int _magicNumbersMaxLength;
+
+  /**
+   * Create a new empty [MimeTypeResolver].
+   */
+  MimeTypeResolver.empty() : _useDefault = false, _magicNumbersMaxLength = 0;
+
+  /**
+   * Create a new [MimeTypeResolver] containing the default scope.
+   */
+  MimeTypeResolver() :
+      _useDefault = true,
+      _magicNumbersMaxLength = _defaultMagicNumbersMaxLength;
+
+  /**
+   * Get the maximum number of bytes required to match all magic numbers, when
+   * performing [lookup] with headerBytes present.
+   */
+  int get magicNumbersMaxLength => _magicNumbersMaxLength;
+
+  /**
+   * Extract the extension from [path] and use that for MIME-type lookup.
+   *
+   * If no matching MIME-type was found, `null` is returned.
+   *
+   * If [headerBytes] is present, a match for known magic-numbers will be
+   * performed first. This allows the correct mime-type to be found, even though
+   * a file have been saved using the wrong file-name extension. If less than
+   * [magicNumbersMaxLength] bytes was provided, some magic-numbers won't
+   * be matched against.
+   */
+  String lookup(String path,
+                {List<int> headerBytes}) {
+    String result;
+    if (headerBytes != null) {
+      result =_matchMagic(headerBytes, _magicNumbers);
+      if (result != null) return result;
+      if (_useDefault) {
+        result =_matchMagic(headerBytes, _defaultMagicNumbers);
+        if (result != null) return result;
+      }
+    }
+    var ext = _ext(path);
+    result = _extensionMap[ext];
+    if (result != null) return result;
+    if (_useDefault) {
+      result = _defaultExtensionMap[ext];
+      if (result != null) return result;
+    }
+    return null;
+  }
+
+  /**
+   * Add a new MIME-type mapping to the [MimeTypeResolver]. If the [extension]
+   * is already present in the [MimeTypeResolver], it'll be overwritten.
+   */
+  void addExtension(String extension, String mimeType) {
+    _extensionMap[extension] = mimeType;
+  }
+
+  /**
+   * Add a new magic-number mapping to the [MimeTypeResolver].
+   *
+   * If [mask] is present,the [mask] is used to only perform matching on
+   * selective bits. The [mask] must have the same length as [bytes].
+   */
+  void addMagicNumber(List<int> bytes, String mimeType, {List<int> mask}) {
+    if (mask != null && bytes.length != mask.length) {
+      throw new ArgumentError('Bytes and mask are of different lengths');
+    }
+    if (bytes.length > _magicNumbersMaxLength) {
+      _magicNumbersMaxLength = bytes.length;
+    }
+    _magicNumbers.add(new _MagicNumber(mimeType, bytes, mask: mask));
+  }
+
+  static String _matchMagic(List<int> headerBytes,
+                            List<_MagicNumber> magicNumbers) {
+    for (var mn in magicNumbers) {
+      if (mn.matches(headerBytes)) return mn.mimeType;
+    }
+    return null;
+  }
+
+  static String _ext(String path) {
+    int index = path.lastIndexOf('.');
+    if (index < 0 || index + 1 >= path.length) return path;
+    return path.substring(index + 1).toLowerCase();
+  }
+}
+
diff --git a/pkg/mime/pubspec.yaml b/pkg/mime/pubspec.yaml
new file mode 100644
index 0000000..82493f8
--- /dev/null
+++ b/pkg/mime/pubspec.yaml
@@ -0,0 +1,5 @@
+name: mime
+author: "Dart Team <misc@dartlang.org>"
+homepage: http://www.dartlang.org
+description: >
+ Helper-package for working with MIME.
diff --git a/pkg/mime/test/mime_type_test.dart b/pkg/mime/test/mime_type_test.dart
new file mode 100644
index 0000000..36c728d
--- /dev/null
+++ b/pkg/mime/test/mime_type_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.
+
+import "package:unittest/unittest.dart";
+import 'package:mime/mime.dart';
+
+void expectMimeType(String path,
+                    String expectedMimeType,
+                    {List<int> headerBytes,
+                     MimeTypeResolver resolver}) {
+  String mimeType;
+  if (resolver == null) {
+    mimeType = lookupMimeType(path, headerBytes: headerBytes);
+  } else {
+    mimeType = resolver.lookup(path, headerBytes: headerBytes);
+  }
+
+  if (mimeType != expectedMimeType) {
+    throw "Expect '$expectedMimeType' but got '$mimeType'";
+  }
+}
+
+void main() {
+  group('global-lookup', () {
+    test('by-path', () {
+      expectMimeType('file.dart', 'application/dart');
+      // Test mixed-case
+      expectMimeType('file.DaRT', 'application/dart');
+      expectMimeType('file.html', 'text/html');
+      expectMimeType('file.xhtml', 'application/xhtml+xml');
+      expectMimeType('file.jpeg', 'image/jpeg');
+      expectMimeType('file.jpg', 'image/jpeg');
+      expectMimeType('file.png', 'image/png');
+      expectMimeType('file.gif', 'image/gif');
+      expectMimeType('file.cc', 'text/x-c');
+      expectMimeType('file.c', 'text/x-c');
+      expectMimeType('file.css', 'text/css');
+      expectMimeType('file.js', 'application/javascript');
+      expectMimeType('file.ps', 'application/postscript');
+      expectMimeType('file.pdf', 'application/pdf');
+      expectMimeType('file.tiff', 'image/tiff');
+      expectMimeType('file.tif', 'image/tiff');
+    });
+
+    test('unknown-mime-type', () {
+      expectMimeType('file.unsupported-extension', null);
+    });
+
+    test('by-header-bytes', () {
+      expectMimeType('file.jpg',
+                     'image/png',
+                     headerBytes: [0x89, 0x50, 0x4E, 0x47,
+                                   0x0D, 0x0A, 0x1A, 0x0A]);
+      expectMimeType('file.jpg',
+                     'image/gif',
+                     headerBytes: [0x47, 0x49, 0x46, 0x38, 0x39,
+                                   0x61, 0x0D, 0x0A, 0x1A, 0x0A]);
+      expectMimeType('file.gif',
+                     'image/jpeg',
+                     headerBytes: [0xFF, 0xD8, 0x46, 0x38, 0x39,
+                                   0x61, 0x0D, 0x0A, 0x1A, 0x0A]);
+      expectMimeType('file.mp4',
+                     'video/mp4',
+                     headerBytes: [0x00, 0x00, 0x00, 0x04, 0x66, 0x74,
+                                   0x79, 0x70, 0x33, 0x67, 0x70, 0x35]);
+    });
+  });
+
+  group('custom-resolver', () {
+    test('override-extension', () {
+      var resolver = new MimeTypeResolver();
+      resolver.addExtension('jpg', 'my-mime-type');
+      expectMimeType('file.jpg', 'my-mime-type', resolver: resolver);
+    });
+
+    test('fallthrough-extension', () {
+      var resolver = new MimeTypeResolver();
+      resolver.addExtension('jpg2', 'my-mime-type');
+      expectMimeType('file.jpg', 'image/jpeg', resolver: resolver);
+    });
+
+    test('with-mask', () {
+      var resolver = new MimeTypeResolver.empty();
+      resolver.addMagicNumber([0x01, 0x02, 0x03],
+                              'my-mime-type',
+                              mask: [0x01, 0xFF, 0xFE]);
+      expectMimeType('file',
+                     'my-mime-type',
+                     headerBytes: [0x01, 0x02, 0x03],
+                     resolver: resolver);
+      expectMimeType('file',
+                     null,
+                     headerBytes: [0x01, 0x03, 0x03],
+                     resolver: resolver);
+      expectMimeType('file',
+                     'my-mime-type',
+                     headerBytes: [0xFF, 0x02, 0x02],
+                     resolver: resolver);
+    });
+  });
+}
+
diff --git a/pkg/pathos/README.md b/pkg/pathos/README.md
index e67fc5e..1e50b23 100644
--- a/pkg/pathos/README.md
+++ b/pkg/pathos/README.md
@@ -216,6 +216,44 @@
 
     withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
 
+### String fromUri(Uri uri)
+
+Returns the path represented by [uri]. For POSIX and Windows styles, [uri] must
+be a `file:` URI. For the URL style, this will just convert [uri] to a string.
+
+    // POSIX
+    path.fromUri(Uri.parse('file:///path/to/foo'))
+      // -> '/path/to/foo'
+
+    // Windows
+    path.fromUri(Uri.parse('file:///C:/path/to/foo'))
+      // -> r'C:\path\to\foo'
+
+    // URL
+    path.fromUri(Uri.parse('http://dartlang.org/path/to/foo'))
+      // -> 'http://dartlang.org/path/to/foo'
+
+### Uri toUri(String path)
+
+Returns the URI that represents [path]. For POSIX and Windows styles, this will
+return a `file:` URI. For the URL style, this will just convert [path] to a
+[Uri].
+
+This will always convert relative paths to absolute ones before converting
+to a URI.
+
+    // POSIX
+    path.toUri('/path/to/foo')
+      // -> Uri.parse('file:///path/to/foo')
+
+    // Windows
+    path.toUri(r'C:\path\to\foo')
+      // -> Uri.parse('file:///C:/path/to/foo')
+
+    // URL
+    path.toUri('http://dartlang.org/path/to/foo')
+      // -> Uri.parse('http://dartlang.org/path/to/foo')
+
 ## The path.Builder class
 
 In addition to the functions, path exposes a `path.Builder` class. This lets
diff --git a/pkg/pathos/lib/path.dart b/pkg/pathos/lib/path.dart
index 145953f..c33bd87 100644
--- a/pkg/pathos/lib/path.dart
+++ b/pkg/pathos/lib/path.dart
@@ -275,6 +275,45 @@
 ///     withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
 String withoutExtension(String path) => _builder.withoutExtension(path);
 
+/// Returns the path represented by [uri].
+///
+/// For POSIX and Windows styles, [uri] must be a `file:` URI. For the URL
+/// style, this will just convert [uri] to a string.
+///
+///     // POSIX
+///     path.fromUri(Uri.parse('file:///path/to/foo'))
+///       // -> '/path/to/foo'
+///
+///     // Windows
+///     path.fromUri(Uri.parse('file:///C:/path/to/foo'))
+///       // -> r'C:\path\to\foo'
+///
+///     // URL
+///     path.fromUri(Uri.parse('http://dartlang.org/path/to/foo'))
+///       // -> 'http://dartlang.org/path/to/foo'
+String fromUri(Uri uri) => _builder.fromUri(uri);
+
+/// Returns the URI that represents [path].
+///
+/// For POSIX and Windows styles, this will return a `file:` URI. For the URL
+/// style, this will just convert [path] to a [Uri].
+///
+/// This will always convert relative paths to absolute ones before converting
+/// to a URI.
+///
+///     // POSIX
+///     path.toUri('/path/to/foo')
+///       // -> Uri.parse('file:///path/to/foo')
+///
+///     // Windows
+///     path.toUri(r'C:\path\to\foo')
+///       // -> Uri.parse('file:///C:/path/to/foo')
+///
+///     // URL
+///     path.toUri('http://dartlang.org/path/to/foo')
+///       // -> Uri.parse('http://dartlang.org/path/to/foo')
+Uri toUri(String path) => _builder.toUri(path);
+
 /// Validates that there are no non-null arguments following a null one and
 /// throws an appropriate [ArgumentError] on failure.
 _validateArgList(String method, List<String> args) {
@@ -436,7 +475,7 @@
   /// On POSIX systems, absolute paths start with a `/` (forward slash). On
   /// Windows, an absolute path starts with `\\`, or a drive letter followed by
   /// `:/` or `:\`.
-  bool isRelative(String path) => !isAbsolute(path);
+  bool isRelative(String path) => !this.isAbsolute(path);
 
   /// Returns `true` if [path] is a root-relative path and `false` if it's not.
   ///
@@ -673,6 +712,48 @@
     return parsed.toString();
   }
 
+  /// Returns the path represented by [uri].
+  ///
+  /// For POSIX and Windows styles, [uri] must be a `file:` URI. For the URL
+  /// style, this will just convert [uri] to a string.
+  ///
+  ///     // POSIX
+  ///     builder.fromUri(Uri.parse('file:///path/to/foo'))
+  ///       // -> '/path/to/foo'
+  ///
+  ///     // Windows
+  ///     builder.fromUri(Uri.parse('file:///C:/path/to/foo'))
+  ///       // -> r'C:\path\to\foo'
+  ///
+  ///     // URL
+  ///     builder.fromUri(Uri.parse('http://dartlang.org/path/to/foo'))
+  ///       // -> 'http://dartlang.org/path/to/foo'
+  String fromUri(Uri uri) => style.pathFromUri(uri);
+
+  /// Returns the URI that represents [path].
+  ///
+  /// For POSIX and Windows styles, this will return a `file:` URI. For the URL
+  /// style, this will just convert [path] to a [Uri].
+  ///
+  ///     // POSIX
+  ///     builder.toUri('/path/to/foo')
+  ///       // -> Uri.parse('file:///path/to/foo')
+  ///
+  ///     // Windows
+  ///     builder.toUri(r'C:\path\to\foo')
+  ///       // -> Uri.parse('file:///C:/path/to/foo')
+  ///
+  ///     // URL
+  ///     builder.toUri('http://dartlang.org/path/to/foo')
+  ///       // -> Uri.parse('http://dartlang.org/path/to/foo')
+  Uri toUri(String path) {
+    if (isRelative(path)) {
+      return Uri.parse(path.replaceAll(style.separatorPattern, '/'));
+    } else {
+      return style.pathToUri(join(root, path));
+    }
+  }
+
   _ParsedPath _parse(String path) {
     var before = path;
 
@@ -711,18 +792,17 @@
 }
 
 /// An enum type describing a "flavor" of path.
-class Style {
+abstract class Style {
   /// POSIX-style paths use "/" (forward slash) as separators. Absolute paths
   /// start with "/". Used by UNIX, Linux, Mac OS X, and others.
-  static final posix = new Style._('posix', '/', '/', r'[^/]$', '/');
+  static final posix = new _PosixStyle();
 
   /// Windows paths use "\" (backslash) as separators. Absolute paths start with
   /// a drive letter followed by a colon (example, "C:") or two backslashes
   /// ("\\") for UNC paths.
   // TODO(rnystrom): The UNC root prefix should include the drive name too, not
   // just the "\\".
-  static final windows = new Style._('windows', '\\', r'[/\\]', r'[^/\\]$',
-      r'\\\\|[a-zA-Z]:[/\\]');
+  static final windows = new _WindowsStyle();
 
   /// URLs aren't filesystem paths, but they're supported by Pathos to make it
   /// easier to manipulate URL paths in the browser.
@@ -730,30 +810,19 @@
   /// URLs use "/" (forward slash) as separators. Absolute paths either start
   /// with a protocol and optional hostname (e.g. `http://dartlang.org`,
   /// `file://`) or with "/".
-  static final url = new Style._('url', '/', '/',
-      r"(^[a-zA-Z][-+.a-zA-Z\d]*://|[^/])$",
-      r"[a-zA-Z][-+.a-zA-Z\d]*://[^/]*", r"/");
-
-  Style._(this.name, this.separator, String separatorPattern,
-      String needsSeparatorPattern, String rootPattern,
-      [String relativeRootPattern])
-    : separatorPattern = new RegExp(separatorPattern),
-      needsSeparatorPattern = new RegExp(needsSeparatorPattern),
-      _rootPattern = new RegExp('^$rootPattern'),
-      _relativeRootPattern = relativeRootPattern == null ? null :
-          new RegExp('^$relativeRootPattern');
+  static final url = new _UrlStyle();
 
   /// The name of this path style. Will be "posix" or "windows".
-  final String name;
+  String get name;
 
   /// The path separator for this style. On POSIX, this is `/`. On Windows,
   /// it's `\`.
-  final String separator;
+  String get separator;
 
   /// The [Pattern] that can be used to match a separator for a path in this
-  /// style. Windows allows both "/" and "\" as path separators even though
-  /// "\" is the canonical one.
-  final Pattern separatorPattern;
+  /// style. Windows allows both "/" and "\" as path separators even though "\"
+  /// is the canonical one.
+  Pattern get separatorPattern;
 
   /// The [Pattern] that matches path components that need a separator after
   /// them.
@@ -763,24 +832,23 @@
   /// separator between the root and the first component, even if the root
   /// already ends in a separator character. For example, to join "file://" and
   /// "usr", an additional "/" is needed (making "file:///usr").
-  final Pattern needsSeparatorPattern;
+  Pattern get needsSeparatorPattern;
 
-  // TODO(nweiz): make this a Pattern when issue 7080 is fixed.
-  /// The [RegExp] that can be used to match the root prefix of an absolute
+  /// The [Pattern] that can be used to match the root prefix of an absolute
   /// path in this style.
-  final RegExp _rootPattern;
+  Pattern get rootPattern;
 
-  /// The [RegExp] that can be used to match the root prefix of a root-relative
+  /// The [Pattern] that can be used to match the root prefix of a root-relative
   /// path in this style.
   ///
   /// This can be null to indicate that this style doesn't support root-relative
   /// paths.
-  final RegExp _relativeRootPattern;
+  final Pattern relativeRootPattern = null;
 
   /// Gets the root prefix of [path] if path is absolute. If [path] is relative,
   /// returns `null`.
   String getRoot(String path) {
-    var match = _rootPattern.firstMatch(path);
+    var match = rootPattern.firstMatch(path);
     if (match != null) return match[0];
     return getRelativeRoot(path);
   }
@@ -789,15 +857,146 @@
   ///
   /// If [path] is relative or absolute and not root-relative, returns `null`.
   String getRelativeRoot(String path) {
-    if (_relativeRootPattern == null) return null;
-    var match = _relativeRootPattern.firstMatch(path);
+    if (relativeRootPattern == null) return null;
+    var match = relativeRootPattern.firstMatch(path);
     if (match == null) return null;
     return match[0];
   }
 
+  /// Returns the path represented by [uri] in this style.
+  String pathFromUri(Uri uri);
+
+  /// Returns the URI that represents [path].
+  ///
+  /// Pathos will always path an absolute path for [path]. Relative paths are
+  /// handled automatically by [Builder].
+  Uri pathToUri(String path);
+
   String toString() => name;
 }
 
+/// The style for POSIX paths.
+class _PosixStyle extends Style {
+  _PosixStyle();
+
+  static final _builder = new Builder(style: Style.posix);
+
+  final name = 'posix';
+  final separator = '/';
+  final separatorPattern = new RegExp(r'/');
+  final needsSeparatorPattern = new RegExp(r'[^/]$');
+  final rootPattern = new RegExp(r'^/');
+
+  String pathFromUri(Uri uri) {
+    if (uri.scheme == '' || uri.scheme == 'file') {
+      return Uri.decodeComponent(uri.path);
+    }
+    throw new ArgumentError("Uri $uri must have scheme 'file:'.");
+  }
+
+  Uri pathToUri(String path) {
+    var parsed = _builder._parse(path);
+
+    if (parsed.parts.isEmpty) {
+      // If the path is a bare root (e.g. "/"), [components] will
+      // currently be empty. We add two empty components so the URL constructor
+      // produces "file:///", with a trailing slash.
+      parsed.parts.addAll(["", ""]);
+    } else if (parsed.hasTrailingSeparator) {
+      // If the path has a trailing slash, add a single empty component so the
+      // URI has a trailing slash as well.
+      parsed.parts.add("");
+    }
+
+    return new Uri(scheme: 'file', pathSegments: parsed.parts);
+  }
+}
+
+/// The style for Windows paths.
+class _WindowsStyle extends Style {
+  _WindowsStyle();
+
+  static final _builder = new Builder(style: Style.windows);
+
+  final name = 'windows';
+  final separator = '\\';
+  final separatorPattern = new RegExp(r'[/\\]');
+  final needsSeparatorPattern = new RegExp(r'[^/\\]$');
+  final rootPattern = new RegExp(r'^(\\\\|[a-zA-Z]:[/\\])');
+
+  String pathFromUri(Uri uri) {
+    if (uri.scheme != '' && uri.scheme != 'file') {
+      throw new ArgumentError("Uri $uri must have scheme 'file:'.");
+    }
+
+    var path = uri.path;
+    if (uri.host == '') {
+      // Drive-letter paths look like "file:///C:/path/to/file". The
+      // replaceFirst removes the extra initial slash.
+      if (path.startsWith('/')) path = path.replaceFirst("/", "");
+    } else {
+      // Network paths look like "file://hostname/path/to/file".
+      path = '\\\\${uri.host}$path';
+    }
+    return Uri.decodeComponent(path.replaceAll("/", "\\"));
+  }
+
+  Uri pathToUri(String path) {
+    var parsed = _builder._parse(path);
+    if (parsed.root == r'\\') {
+      // Network paths become "file://hostname/path/to/file".
+
+      var host = parsed.parts.removeAt(0);
+
+      if (parsed.parts.isEmpty) {
+        // If the path is a bare root (e.g. "\\hostname"), [parsed.parts] will
+        // currently be empty. We add two empty components so the URL
+        // constructor produces "file://hostname/", with a trailing slash.
+        parsed.parts.addAll(["", ""]);
+      } else if (parsed.hasTrailingSeparator) {
+        // If the path has a trailing slash, add a single empty component so the
+        // URI has a trailing slash as well.
+        parsed.parts.add("");
+      }
+
+      return new Uri(scheme: 'file', host: host, pathSegments: parsed.parts);
+    } else {
+      // Drive-letter paths become "file:///C:/path/to/file".
+
+      // If the path is a bare root (e.g. "C:\"), [parsed.parts] will currently
+      // be empty. We add an empty component so the URL constructor produces
+      // "file:///C:/", with a trailing slash. We also add an empty component if
+      // the URL otherwise has a trailing slash.
+      if (parsed.parts.length == 0 || parsed.hasTrailingSeparator) {
+        parsed.parts.add("");
+      }
+
+      // Get rid of the trailing "\" in "C:\" because the URI constructor will
+      // add a separator on its own.
+      parsed.parts.insert(0, parsed.root.replaceAll(separatorPattern, ""));
+
+      return new Uri(scheme: 'file', pathSegments: parsed.parts);
+    }
+  }
+}
+
+/// The style for URL paths.
+class _UrlStyle extends Style {
+  _UrlStyle();
+
+  final name = 'url';
+  final separator = '/';
+  final separatorPattern = new RegExp(r'/');
+  final needsSeparatorPattern = new RegExp(
+      r"(^[a-zA-Z][-+.a-zA-Z\d]*://|[^/])$");
+  final rootPattern = new RegExp(r"[a-zA-Z][-+.a-zA-Z\d]*://[^/]*");
+  final relativeRootPattern = new RegExp(r"^/");
+
+  String pathFromUri(Uri uri) => uri.toString();
+
+  Uri pathToUri(String path) => Uri.parse(path);
+}
+
 // TODO(rnystrom): Make this public?
 class _ParsedPath {
   /// The [Style] that was used to parse this path.
@@ -848,6 +1047,8 @@
     return copy._splitExtension()[0];
   }
 
+  bool get hasTrailingSeparator => !parts.isEmpty && (parts.last == '' || separators.last != '');
+
   void removeTrailingSeparators() {
     while (!parts.isEmpty && parts.last == '') {
       parts.removeLast();
diff --git a/pkg/pathos/test/pathos_posix_test.dart b/pkg/pathos/test/pathos_posix_test.dart
index ecdd133..a446f76 100644
--- a/pkg/pathos/test/pathos_posix_test.dart
+++ b/pkg/pathos/test/pathos_posix_test.dart
@@ -399,4 +399,26 @@
     expect(builder.withoutExtension('a/b.c/'), 'a/b/');
     expect(builder.withoutExtension('a/b.c//'), 'a/b//');
   });
+
+  test('fromUri', () {
+    expect(builder.fromUri(Uri.parse('file:///path/to/foo')), '/path/to/foo');
+    expect(builder.fromUri(Uri.parse('file:///path/to/foo/')), '/path/to/foo/');
+    expect(builder.fromUri(Uri.parse('file:///')), '/');
+    expect(builder.fromUri(Uri.parse('foo/bar')), 'foo/bar');
+    expect(builder.fromUri(Uri.parse('/path/to/foo')), '/path/to/foo');
+    expect(builder.fromUri(Uri.parse('///path/to/foo')), '/path/to/foo');
+    expect(builder.fromUri(Uri.parse('file:///path/to/foo%23bar')),
+        '/path/to/foo#bar');
+    expect(() => builder.fromUri(Uri.parse('http://dartlang.org')),
+        throwsArgumentError);
+  });
+
+  test('toUri', () {
+    expect(builder.toUri('/path/to/foo'), Uri.parse('file:///path/to/foo'));
+    expect(builder.toUri('/path/to/foo/'), Uri.parse('file:///path/to/foo/'));
+    expect(builder.toUri('/'), Uri.parse('file:///'));
+    expect(builder.toUri('foo/bar'), Uri.parse('foo/bar'));
+    expect(builder.toUri('/path/to/foo#bar'),
+        Uri.parse('file:///path/to/foo%23bar'));
+  });
 }
diff --git a/pkg/pathos/test/pathos_url_test.dart b/pkg/pathos/test/pathos_url_test.dart
index b8c100f..ff1af86 100644
--- a/pkg/pathos/test/pathos_url_test.dart
+++ b/pkg/pathos/test/pathos_url_test.dart
@@ -625,4 +625,29 @@
     expect(builder.withoutExtension('a/b.c/'), 'a/b/');
     expect(builder.withoutExtension('a/b.c//'), 'a/b//');
   });
+
+
+  test('fromUri', () {
+    expect(builder.fromUri(Uri.parse('http://dartlang.org/path/to/foo')),
+        'http://dartlang.org/path/to/foo');
+    expect(builder.fromUri(Uri.parse('http://dartlang.org/path/to/foo/')),
+        'http://dartlang.org/path/to/foo/');
+    expect(builder.fromUri(Uri.parse('file:///path/to/foo')),
+        'file:///path/to/foo');
+    expect(builder.fromUri(Uri.parse('foo/bar')), 'foo/bar');
+    expect(builder.fromUri(Uri.parse('http://dartlang.org/path/to/foo%23bar')),
+        'http://dartlang.org/path/to/foo%23bar');
+  });
+
+  test('toUri', () {
+    expect(builder.toUri('http://dartlang.org/path/to/foo'),
+        Uri.parse('http://dartlang.org/path/to/foo'));
+    expect(builder.toUri('http://dartlang.org/path/to/foo/'),
+        Uri.parse('http://dartlang.org/path/to/foo/'));
+    expect(builder.toUri('file:///path/to/foo'),
+        Uri.parse('file:///path/to/foo'));
+    expect(builder.toUri('foo/bar'), Uri.parse('foo/bar'));
+    expect(builder.toUri('http://dartlang.org/path/to/foo%23bar'),
+        Uri.parse('http://dartlang.org/path/to/foo%23bar'));
+  });
 }
diff --git a/pkg/pathos/test/pathos_windows_test.dart b/pkg/pathos/test/pathos_windows_test.dart
index 6d22742..a7c8182 100644
--- a/pkg/pathos/test/pathos_windows_test.dart
+++ b/pkg/pathos/test/pathos_windows_test.dart
@@ -441,4 +441,38 @@
     expect(builder.withoutExtension(r'a.b/c'), r'a.b/c');
     expect(builder.withoutExtension(r'a\b.c\'), r'a\b\');
   });
+
+  test('fromUri', () {
+    expect(builder.fromUri(Uri.parse('file:///C:/path/to/foo')),
+        r'C:\path\to\foo');
+    expect(builder.fromUri(Uri.parse('file://hostname/path/to/foo')),
+        r'\\hostname\path\to\foo');
+    expect(builder.fromUri(Uri.parse('file:///C:/')), r'C:\');
+    expect(builder.fromUri(Uri.parse('file://hostname/')), r'\\hostname\');
+    expect(builder.fromUri(Uri.parse('foo/bar')), r'foo\bar');
+    expect(builder.fromUri(Uri.parse('/C:/path/to/foo')), r'C:\path\to\foo');
+    expect(builder.fromUri(Uri.parse('///C:/path/to/foo')), r'C:\path\to\foo');
+    expect(builder.fromUri(Uri.parse('//hostname/path/to/foo')),
+        r'\\hostname\path\to\foo');
+    expect(builder.fromUri(Uri.parse('file:///C:/path/to/foo%23bar')),
+        r'C:\path\to\foo#bar');
+    expect(builder.fromUri(Uri.parse('file://hostname/path/to/foo%23bar')),
+        r'\\hostname\path\to\foo#bar');
+    expect(() => builder.fromUri(Uri.parse('http://dartlang.org')),
+        throwsArgumentError);
+  });
+
+  test('toUri', () {
+    expect(builder.toUri(r'C:\path\to\foo'),
+        Uri.parse('file:///C:/path/to/foo'));
+    expect(builder.toUri(r'C:\path\to\foo\'),
+        Uri.parse('file:///C:/path/to/foo/'));
+    expect(builder.toUri(r'C:\'), Uri.parse('file:///C:/'));
+    expect(builder.toUri(r'\\hostname\'), Uri.parse('file://hostname/'));
+    expect(builder.toUri(r'foo\bar'), Uri.parse('foo/bar'));
+    expect(builder.toUri(r'C:\path\to\foo#bar'),
+        Uri.parse('file:///C:/path/to/foo%23bar'));
+    expect(builder.toUri(r'\\hostname\path\to\foo#bar'),
+        Uri.parse('file://hostname/path/to/foo%23bar'));
+  });
 }
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 1a4e87f..da54056 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -27,6 +27,8 @@
 # testing.
 webdriver/test/webdriver_test: Skip
 
+[ $compiler == dart2js && $runtime == ff ]
+unittest/test/unittest_test: Pass, Timeout # http://dartbug.com/11473
 
 [ $runtime == d8 || $runtime == jsshell ]
 unittest/test/unittest_test: Pass, Fail # http://dartbug.com/10109
@@ -48,6 +50,8 @@
 
 [ $runtime == safari ]
 fixnum/test/int_64_test: Pass, Fail # Bug in JSC.
+crypto/test/hmac_sha1_test: Fail # Issue 11407.
+crypto/test/sha1_test: Fail # Issue 11407.
 
 # Skip browser-specific tests on VM
 [ $runtime == vm ]
@@ -64,11 +68,17 @@
 analyzer_experimental/test/generated/ast_test: Fail, Slow # Issue 11230
 unittest/test/instance_test: Fail # http://dartbug.com/11191
 
+[ $compiler == dart2js && $checked ]
+mdv_observe/test/observable_map_test: Fail # BUG(11480): Triage.
+
 [ $compiler == dartc ]
 unittest/test/mock_regexp_negative_test: Fail
 unittest/test/mock_stepwise_negative_test: Fail
 
 [ $compiler == dartanalyzer ]
+# test issue https://code.google.com/p/dart/issues/detail?id=11517
+# These tests are not negetive statically.
+# Requested test fix or permission to mark 'fail, OK'
 unittest/test/mock_regexp_negative_test: fail
 unittest/test/mock_stepwise_negative_test: fail
 
@@ -83,12 +93,6 @@
 serialization/test/no_library_test: Fail # Issue 6490
 
 [ $compiler == dart2js && $minified ]
-# The unittest package relies on getting the original (non-minified) method
-# names in Invocation.  You can't get that when minifying.
-# TODO(ahe/erikcorry): But soon you can, now that we use Symbol.
-unittest/test/mock_test: Fail
-unittest/test/mock_regexp_negative_test: Fail
-
 serialization/test/serialization_test: Fail # Issue 6490
 serialization/test/no_library_test: Fail # Issue 6490
 
@@ -105,15 +109,13 @@
 crypto/test/sha256_test: Slow, Pass
 crypto/test/sha1_test: Slow, Pass
 
-[ $compiler == dart2js && $checked ]
-pathos/test/pathos_dartium_test: Crash
-
 [ $browser ]
 analyzer_experimental/test/error_test: Fail, OK # Uses dart:io.
 analyzer_experimental/test/generated/element_test: Fail, OK # Uses dart:io.
 analyzer_experimental/test/generated/resolver_test: Fail, OK # Uses dart:io.
 analyzer_experimental/test/options_test: Fail, OK # Uses dart:io.
 analyzer_experimental/test/services/formatter_test: Fail, OK # Uses dart:io.
+barback/test/*: Fail, OK # Uses dart:io.
 http/test/client_test: Fail, OK # Uses dart:io.
 http/test/http_test: Fail, OK # Uses dart:io.
 http/test/mock_client_test: Fail, OK # Uses dart:io.
@@ -121,6 +123,7 @@
 http/test/request_test: Fail, OK # Uses dart:io.
 http/test/response_test: Fail, OK # Uses dart:io.
 http/test/streamed_request_test: Fail, OK # Uses dart:io.
+http_server/test/*: Fail, OK # Uses dart:io.
 intl/test/date_time_format_file_even_test: Fail, OK # Uses dart:io.
 intl/test/date_time_format_file_odd_test: Fail, OK # Uses dart:io.
 intl/test/find_default_locale_standalone_test: Fail, OK # Uses dart:io.
diff --git a/pkg/scheduled_test/test/metatest.dart b/pkg/scheduled_test/test/metatest.dart
index 71ad421..9bbd2e4 100644
--- a/pkg/scheduled_test/test/metatest.dart
+++ b/pkg/scheduled_test/test/metatest.dart
@@ -133,9 +133,9 @@
 /// describing the results of that test run.
 Future<Map> _runInIsolate(String description) {
   // TODO(nweiz): Don't use path here once issue 8440 is fixed.
-  var future = spawnUri(path.join(path.current, new Options().script)).call({
+  var future = spawnUri(path.join(path.current, Platform.script)).call({
     'testToRun': description,
-    'executable': new Options().executable
+    'executable': Platform.executable
   });
   // TODO(nweiz): Remove this timeout once issue 8417 is fixed and we can
   // capture top-level exceptions.
diff --git a/pkg/scheduled_test/test/scheduled_process_test.dart b/pkg/scheduled_test/test/scheduled_process_test.dart
index f24758c..3f07c66 100644
--- a/pkg/scheduled_test/test/scheduled_process_test.dart
+++ b/pkg/scheduled_test/test/scheduled_process_test.dart
@@ -365,8 +365,7 @@
 
   var dartPath = schedule(() {
     return tempDir.then((dir) {
-      var utilsPath = path.absolute(path.join(
-          new Options().script, 'utils.dart'));
+      var utilsPath = path.absolute(path.join(Platform.script, 'utils.dart'));
       return new File(path.join(dir, 'test.dart')).writeAsString('''
           import 'dart:async';
           import 'dart:io';
diff --git a/pkg/serialization/lib/src/format.dart b/pkg/serialization/lib/src/format.dart
index 93a345b..2c71e42 100644
--- a/pkg/serialization/lib/src/format.dart
+++ b/pkg/serialization/lib/src/format.dart
@@ -67,7 +67,7 @@
    * the data also includes rule definitions, then these will replace the rules
    * in the [Serialization] for [reader].
    */
-  Map<String, dynamic> read(topLevel, Reader reader) {
+  Map<String, dynamic> read(Map<String, dynamic> topLevel, Reader reader) {
     var ruleString = topLevel["rules"];
     reader.readRules(ruleString);
     reader._data = topLevel["data"];
@@ -150,7 +150,7 @@
    * the data also includes rule definitions, then these will replace the rules
    * in the [Serialization] for [reader].
    */
-  Map<String, dynamic> read(topLevel, Reader reader) {
+  Map<String, dynamic> read(Map<String, dynamic> topLevel, Reader reader) {
     super.read(topLevel, reader);
     forAllStates(reader,
         (ref) => ref is Map && ref["__Ref"] != null,
diff --git a/pkg/serialization/lib/src/serialization_helpers.dart b/pkg/serialization/lib/src/serialization_helpers.dart
index 1f86a97..87fe55c 100644
--- a/pkg/serialization/lib/src/serialization_helpers.dart
+++ b/pkg/serialization/lib/src/serialization_helpers.dart
@@ -190,7 +190,7 @@
   final List<K> keys = <K>[];
   final List<V> values = <V>[];
 
-  V operator [](K key) {
+  V operator [](Object key) {
     var index =  _indexOf(key);
     return (index == -1) ? null : values[index];
   }
@@ -205,7 +205,7 @@
     }
   }
 
-  putIfAbsent(K key, Function ifAbsent) {
+  V putIfAbsent(K key, Function ifAbsent) {
     var index = _indexOf(key);
     if (index == -1) {
       keys.add(key);
@@ -216,7 +216,7 @@
     }
   }
 
-  _indexOf(K key) {
+  int _indexOf(Object key) {
     // Go backwards on the guess that we are most likely to access the most
     // recently added.
     // Make strings and primitives unique
@@ -228,14 +228,14 @@
     return -1;
   }
 
-  bool containsKey(K key) => _indexOf(key) != -1;
+  bool containsKey(Object key) => _indexOf(key) != -1;
   void forEach(f(K key, V value)) {
     for (var i = 0; i < keys.length; i++) {
       f(keys[i], values[i]);
     }
   }
 
-  V remove(K key) {
+  V remove(Object key) {
     var index = _indexOf(key);
     if (index == -1) return null;
     keys.removeAt(index);
@@ -251,5 +251,11 @@
   bool get isNotEmpty => !isEmpty;
 
   // Note that this is doing an equality comparison.
-  bool containsValue(x) => values.contains(x);
+  bool containsValue(Object x) => values.contains(x);
+
+  void addAll(Map<K, V> other) {
+    other.forEach((K key, V value) {
+      this[key] = value;
+    });
+  }
 }
diff --git a/pkg/serialization/lib/src/serialization_rule.dart b/pkg/serialization/lib/src/serialization_rule.dart
index aad0aaf..ddfac08 100644
--- a/pkg/serialization/lib/src/serialization_rule.dart
+++ b/pkg/serialization/lib/src/serialization_rule.dart
@@ -546,8 +546,9 @@
   }
   operator []=(x, y) => _throw();
   putIfAbsent(x, y) => _throw();
-  remove(x) => _throw();
-  clear() => _throw();
+  bool remove(x) => _throw();
+  void clear() => _throw();
+  void addAll(Map other) => _throw();
 }
 
 /**
@@ -557,55 +558,20 @@
  * looks like it's just a list of objects to a [CustomRule] without needing
  * to inflate all the references in advance.
  */
-class _LazyList extends IterableBase implements List {
+class _LazyList extends IterableBase with ListMixin implements List {
   _LazyList(this._raw, this._reader);
 
   final List _raw;
   final Reader _reader;
 
-  // This is the only operation that really matters.
-  operator [](x) => _reader.inflateReference(_raw[x]);
-
+  operator [](int x) => _reader.inflateReference(_raw[x]);
   int get length => _raw.length;
-  bool get isEmpty => _raw.isEmpty;
-  get first => _reader.inflateReference(_raw.first);
-  get last => _reader.inflateReference(_raw.last);
 
-  // These operations, and other inherited methods that iterate over the whole
-  // list will work, but may be expensive, and are probably
-  // best avoided.
-  Iterable get _inflated => _raw.map(_reader.inflateReference);
-  Iterator get iterator => _inflated.iterator;
-  indexOf(x, [pos = 0]) => _inflated.toList().indexOf(x);
-  lastIndexOf(x, [pos]) => _inflated.toList().lastIndexOf(x);
-  sublist(start, [end]) => _inflated.sublist(start, end);
+  void set length(int value) => _throw();
 
-  Map<int, dynamic> asMap() => _inflated.asMap();
+  void operator []=(int index, value) => _throw();
 
-  // These operations are all invalid
-  _throw() {
+  void _throw() {
     throw new UnsupportedError("Not modifiable");
   }
-  operator []=(x, y) => _throw();
-  add(x) => _throw();
-  addAll(x) => _throw();
-  sort([f]) => _throw();
-  clear() => _throw();
-  insert(x, y) => _throw();
-  insertAll(x, y) => _throw();
-  fillRange(x, y, [z]) => _throw();
-  removeAt(x) => _throw();
-  remove(x) => _throw();
-  removeLast() => _throw();
-  removeAll(x) => _throw();
-  retainAll(x) => _throw();
-  removeWhere(x) => _throw();
-  retainWhere(x) => _throw();
-  replaceRange(x, y, z) => _throw();
-  getRange(x, y) => _throw();
-  setRange(x, y, z, [a = 0]) => _throw();
-  setAll(x, y) => _throw();
-  removeRange(x, y) => _throw();
-  get reversed => _throw();
-  void set length(x) => _throw();
 }
diff --git a/pkg/serialization/test/serialization_test.dart b/pkg/serialization/test/serialization_test.dart
index 1b79206..1e2d3aa 100644
--- a/pkg/serialization/test/serialization_test.dart
+++ b/pkg/serialization/test/serialization_test.dart
@@ -13,7 +13,7 @@
 
 part 'test_models.dart';
 
-main() {
+void main() {
   var p1 = new Person();
   var a1 = new Address();
   a1.street = 'N 34th';
@@ -554,14 +554,14 @@
       var s = nodeSerializerReflective(n1);
       var output = s.write(n2);
       var port = spawnFunction(echo);
-      port.call(output).then(expectAsync1((input) => verify(input)));
+      return port.call(output).then(verify);
   });
 }
 
 /**
  * Verify serialized output that we have passed to an isolate and back.
  */
-verify(input) {
+void verify(input) {
   var s2 = nodeSerializerReflective(new Node("a"));
   var reader = new Reader(s2);
   var m2 = reader.read(input);
@@ -718,7 +718,7 @@
  * Run a round-trip test on a simple tree of nodes, using a serialization
  * that's returned by the [serializerSetUp] function.
  */
-runRoundTripTest(Function serializerSetUp) {
+void runRoundTripTest(Function serializerSetUp) {
   Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3");
   n1.children = [n2, n3];
   n2.parent = n1;
@@ -744,7 +744,7 @@
  * Run a round-trip test on a simple of nodes, but using the flat format
  * rather than the maps.
  */
-runRoundTripTestFlat(serializerSetUp) {
+void runRoundTripTestFlat(serializerSetUp) {
   Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3");
   n1.children = [n2, n3];
   n2.parent = n1;
@@ -768,7 +768,7 @@
 }
 
 /** Extract the state from [object] using the rules in [s] and return it. */
-states(object, Serialization s) {
+List states(object, Serialization s) {
   var rules = s.rulesFor(object, null);
   return rules.map((x) => x.extractState(object, doNothing, null)).toList();
 }
@@ -816,7 +816,7 @@
  * Function used in an isolate to make sure that the output passes through
  * isolate serialization properly.
  */
-echo() {
+void echo() {
   port.receive((msg, reply) {
     reply.send(msg);
   });
diff --git a/pkg/stack_trace/lib/src/frame.dart b/pkg/stack_trace/lib/src/frame.dart
index 8f1931b..d750b91 100644
--- a/pkg/stack_trace/lib/src/frame.dart
+++ b/pkg/stack_trace/lib/src/frame.dart
@@ -8,7 +8,6 @@
 import 'package:pathos/path.dart' as path;
 
 import 'trace.dart';
-import 'utils.dart';
 
 final _nativeFrameRegExp = new RegExp(
     r'^#\d+\s+([^\s].*) \((.+):(\d+):(\d+)\)$');
@@ -43,12 +42,11 @@
   /// Returns a human-friendly description of the library that this stack frame
   /// comes from.
   ///
-  /// This will usually be the string form of [uri], but a relative path will be
+  /// This will usually be the string form of [uri], but a relative URI will be
   /// used if possible.
   String get library {
-    // TODO(nweiz): handle relative URIs here as well once pathos supports that.
     if (uri.scheme != 'file') return uri.toString();
-    return path.relative(fileUriToPath(uri));
+    return path.relative(path.fromUri(uri));
   }
 
   /// Returns the name of the package this stack frame comes from, or `null` if
diff --git a/pkg/stack_trace/test/frame_test.dart b/pkg/stack_trace/test/frame_test.dart
index d1f53f6..a140670 100644
--- a/pkg/stack_trace/test/frame_test.dart
+++ b/pkg/stack_trace/test/frame_test.dart
@@ -7,7 +7,6 @@
 import 'dart:io';
 
 import 'package:pathos/path.dart' as path;
-import 'package:stack_trace/src/utils.dart';
 import 'package:stack_trace/stack_trace.dart';
 import 'package:unittest/unittest.dart';
 
@@ -41,7 +40,7 @@
     // TODO(nweiz): use URL-style paths when such a thing exists.
     var builder = new path.Builder(style: path.Style.posix);
     expect(builder.basename(frame.uri.path), equals('frame_test.dart'));
-    expect(frame.line, equals(16));
+    expect(frame.line, equals(15));
     expect(frame.column, equals(5));
     expect(frame.member, equals('getStackFrame'));
   });
@@ -115,9 +114,8 @@
     });
 
     test('returns the relative path for file URIs', () {
-      var uri = pathToFileUri(path.join('foo', 'bar.dart'));
-      expect(new Frame.parse('#0 Foo ($uri:0:0)').library,
-          equals(path.join('foo', 'bar.dart')));
+      expect(new Frame.parse('#0 Foo (foo/bar.dart:0:0)').library,
+          equals('foo/bar.dart'));
     });
   });
 
@@ -127,9 +125,8 @@
       expect(new Frame.parse('#0 Foo '
               '(http://dartlang.org/thing.dart:5:10)').location,
           equals('http://dartlang.org/thing.dart 5:10'));
-      var uri = pathToFileUri(path.join('foo', 'bar.dart'));
-      expect(new Frame.parse('#0 Foo ($uri:1:2)').location,
-          equals('${path.join('foo', 'bar.dart')} 1:2'));
+      expect(new Frame.parse('#0 Foo (foo/bar.dart:1:2)').location,
+          equals('foo/bar.dart 1:2'));
     });
   });
 
diff --git a/pkg/stack_trace/test/trace_test.dart b/pkg/stack_trace/test/trace_test.dart
index 902ae80..fcf4fe5 100644
--- a/pkg/stack_trace/test/trace_test.dart
+++ b/pkg/stack_trace/test/trace_test.dart
@@ -7,7 +7,6 @@
 import 'dart:io';
 
 import 'package:pathos/path.dart' as path;
-import 'package:stack_trace/src/utils.dart';
 import 'package:stack_trace/stack_trace.dart';
 import 'package:unittest/unittest.dart';
 
@@ -91,15 +90,14 @@
   });
 
   test('.toString() nicely formats the stack trace', () {
-    var uri = pathToFileUri(path.join('foo', 'bar.dart'));
     var trace = new Trace.parse('''
-#0      Foo._bar ($uri:42:21)
+#0      Foo._bar (foo/bar.dart:42:21)
 #1      zip.<anonymous closure>.zap (dart:async/future.dart:0:2)
 #2      zip.<anonymous closure>.zap (http://pub.dartlang.org/thing.dart:1:100)
 ''');
 
     expect(trace.toString(), equals('''
-${path.join('foo', 'bar.dart')} 42:21                        Foo._bar
+foo/bar.dart 42:21                        Foo._bar
 dart:async/future.dart 0:2                zip.<fn>.zap
 http://pub.dartlang.org/thing.dart 1:100  zip.<fn>.zap
 '''));
diff --git a/pkg/unittest/lib/src/core_matchers.dart b/pkg/unittest/lib/src/core_matchers.dart
index 4b5bdbb..ca7cfb6 100644
--- a/pkg/unittest/lib/src/core_matchers.dart
+++ b/pkg/unittest/lib/src/core_matchers.dart
@@ -87,7 +87,7 @@
  */
 Matcher equals(expected, [limit=100]) =>
     expected is String
-        ? new _StringEqualsMatcher(expected) 
+        ? new _StringEqualsMatcher(expected)
         : new _DeepMatcher(expected, limit);
 
 class _DeepMatcher extends BaseMatcher {
@@ -106,8 +106,8 @@
     var actualIterator = actual.iterator;
     var index = 0;
     while (true) {
+      var newLocation = '${location}[${index}]';
       if (expectedIterator.moveNext()) {
-        var newLocation = '${location}[${index}]';
         if (actualIterator.moveNext()) {
           var rp = matcher(expectedIterator.current,
                            actualIterator.current, newLocation,
@@ -220,7 +220,7 @@
   Description describeMismatch(item, Description mismatchDescription,
                                Map matchState, bool verbose) {
     var reason = matchState['reason'];
-    // If we didn't get a good reason, that would normally be a 
+    // If we didn't get a good reason, that would normally be a
     // simple 'is <value>' message. We only add that if the mismatch
     // description is non empty (so we are supplementing the mismatch
     // description).
diff --git a/pkg/unittest/lib/src/interfaces.dart b/pkg/unittest/lib/src/interfaces.dart
index 660c49f..f45e164 100644
--- a/pkg/unittest/lib/src/interfaces.dart
+++ b/pkg/unittest/lib/src/interfaces.dart
@@ -26,6 +26,8 @@
  * some cases - e.g. language conversion.
  */
 abstract class Description {
+  int get length;
+
   /** Change the value of the description. */
   Description replace(String text);
 
diff --git a/pkg/unmodifiable_collection/lib/unmodifiable_collection.dart b/pkg/unmodifiable_collection/lib/unmodifiable_collection.dart
new file mode 100644
index 0000000..dbdf64d
--- /dev/null
+++ b/pkg/unmodifiable_collection/lib/unmodifiable_collection.dart
@@ -0,0 +1,234 @@
+// 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.
+
+/**
+ * Unmodifiable wrappers for [List], [Set] and [Map] objects.
+ *
+ * The wrappers allow reading from the source list, but writing is prohibited.
+ *
+ * A non-growable list wrapper allows writing as well, but not changing the
+ * list's length.
+ */
+library unmodifiable_collection;
+
+export "dart:collection" show UnmodifiableListView;
+
+/**
+ * A [List] wrapper that acts as a non-growable list.
+ *
+ * Writes to the list are written through to the source list, but operations
+ * that change the length is not allowed.
+ */
+class NonGrowableListView<E> extends _IterableView<E>
+                                     implements List<E> {
+  List<E> _source;
+  NonGrowableListView(List<E> source) : _source = source;
+
+  static void _throw() {
+    throw new UnsupportedError(
+        "Cannot change the length of a fixed-length list");
+  }
+
+  int get length => _source.length;
+
+  E operator [](int index) => _source[index];
+
+  int indexOf(E element, [int start = 0]) => _source.indexOf(element, start);
+
+  int lastIndexOf(E element, [int start])
+      => _source.lastIndexOf(element, start);
+
+  Iterable<E> getRange(int start, int end) => _source.getRange(start, end);
+
+  List<E> sublist(int start, [int end]) => _source.sublist(start, end);
+
+  Iterable<E> get reversed => _source.reversed;
+
+  Map<int, E> asMap() => _source.asMap();
+
+
+  void operator []=(int index, E value) { _source[index] = value; }
+
+  void sort([int compare(E a, E b)]) { _source.sort(compare); }
+
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    _source.setRange(start, end, iterable, skipCount);
+  }
+
+  void fillRange(int start, int end, [E fillValue]) {
+    _source.fillRange(start, end, fillValue);
+  }
+
+  void setAll(int index, Iterable<E> iterable) {
+    _source.setAll(index, iterable);
+  }
+
+
+  void set length(int newLength) => _throw();
+
+  void add(E value) => _throw();
+
+  void addAll(Iterable<E> iterable) => _throw();
+
+  void insert(int index, E element) => _throw();
+
+  void insertAll(int index, Iterable<E> iterable) => _throw();
+
+  bool remove(Object value) { _throw(); }
+
+  E removeAt(int index) { _throw(); }
+
+  E removeLast() { _throw(); }
+
+  void removeWhere(bool test(E element)) => _throw();
+
+  void retainWhere(bool test(E element)) => _throw();
+
+  void removeRange(int start, int end) => _throw();
+
+  void replaceRange(int start, int end, Iterable<E> iterable) => _throw();
+
+  void clear() => _throw();
+}
+
+/**
+ * A [Set] wrapper that acts as an unmodifiable set.
+ */
+class UnmodifiableSetView<E> extends _IterableView<E>
+                                      implements Set<E> {
+  Set<E> _source;
+  UnmodifiableSetView(Set<E> source) : _source = source;
+
+  void _throw() {
+    throw new UnsupportedError("Cannot modify an unmodifiable Set");
+  }
+
+  bool containsAll(Iterable<E> other) => _source.containsAll(other);
+
+  Set<E> intersection(Set<E> other) => _source.intersection(other);
+
+  Set<E> union(Set<E> other) => _source.union(other);
+
+  Set<E> difference(Set<E> other) => _source.difference(other);
+
+
+  void add(E value) => _throw();
+
+  void addAll(Iterable<E> elements) => _throw();
+
+  bool remove(Object value) { _throw(); }
+
+  void removeAll(Iterable elements) => _throw();
+
+  void retainAll(Iterable elements) => _throw();
+
+  void removeWhere(bool test(E element)) => _throw();
+
+  void retainWhere(bool test(E element)) => _throw();
+
+  void clear() => _throw();
+}
+
+/**
+ * A [Map] wrapper that acts as an unmodifiable map.
+ */
+class UnmodifiableMapView<K, V> implements Map<K, V> {
+  Map<K, V> _source;
+  UnmodifiableMapView(Map<K, V> source) : _source = source;
+
+  static void _throw() {
+    throw new UnsupportedError("Cannot modify an unmodifiable Map");
+  }
+
+  int get length => _source.length;
+
+  bool get isEmpty => _source.isEmpty;
+
+  bool get isNotEmpty => _source.isNotEmpty;
+
+  V operator [](K key) => _source[key];
+
+  bool containsKey(K key) => _source.containsKey(key);
+
+  bool containsValue(V value) => _source.containsValue(value);
+
+  void forEach(void f(K key, V value)) => _source.forEach(f);
+
+  Iterable<K> get keys => _source.keys;
+
+  Iterable<V> get values => _source.values;
+
+
+  void operator []=(K key, V value) => _throw();
+
+  V putIfAbsent(K key, V ifAbsent()) { _throw(); }
+
+  void addAll(Map<K, V> other) => _throw();
+
+  V remove(K key) { _throw(); }
+
+  void clear() => _throw();
+}
+
+abstract class _IterableView<E> {
+  Iterable<E> get _source;
+
+  bool any(bool test(E element)) => _source.any(test);
+
+  bool contains(E element) => _source.contains(element);
+
+  E elementAt(int index) => _source.elementAt(index);
+
+  bool every(bool test(E element)) => _source.every(test);
+
+  Iterable expand(Iterable f(E element)) => _source.expand(f);
+
+  E get first => _source.first;
+
+  E firstWhere(bool test(E element), { E orElse() })
+      => _source.firstWhere(test, orElse: orElse);
+
+  dynamic fold(var initialValue,
+               dynamic combine(var previousValue, E element))
+      => _source.fold(initialValue, combine);
+
+  void forEach(void f(E element)) => _source.forEach(f);
+
+  bool get isEmpty => _source.isEmpty;
+
+  bool get isNotEmpty => _source.isNotEmpty;
+
+  Iterator<E> get iterator => _source.iterator;
+
+  String join([String separator = ""]) => _source.join(separator);
+
+  E get last => _source.last;
+
+  E lastWhere(bool test(E element), {E orElse()})
+      => _source.lastWhere(test, orElse: orElse);
+
+  int get length => _source.length;
+
+  Iterable map(f(E element)) => _source.map(f);
+
+  E reduce(E combine(E value, E element)) => _source.reduce(combine);
+
+  E get single => _source.single;
+
+  E singleWhere(bool test(E element)) => _source.singleWhere(test);
+
+  Iterable<E> skip(int n) => _source.skip(n);
+
+  Iterable<E> skipWhile(bool test(E value)) => _source.skipWhile(test);
+
+  Iterable<E> take(int n) => _source.take(n);
+
+  Iterable<E> takeWhile(bool test(E value)) => _source.takeWhile(test);
+
+  List<E> toList({ bool growable: true }) => _source.toList(growable: growable);
+
+  Set<E> toSet() => _source.toSet();
+
+  Iterable<E> where(bool test(E element)) => _source.where(test);
+}
diff --git a/pkg/unmodifiable_collection/pubspec.yaml b/pkg/unmodifiable_collection/pubspec.yaml
new file mode 100644
index 0000000..43cbc11
--- /dev/null
+++ b/pkg/unmodifiable_collection/pubspec.yaml
@@ -0,0 +1,7 @@
+name: unmodifiable_collection
+author: "Dart Team <misc@dartlang.org>"
+homepage: http://www.dartlang.org
+description: >
+  Unmodifiable wrappers for base collection types.
+dev_dependencies:
+  unittest: any
diff --git a/pkg/unmodifiable_collection/test/unmodifiable_collection_test.dart b/pkg/unmodifiable_collection/test/unmodifiable_collection_test.dart
new file mode 100644
index 0000000..2e96e48
--- /dev/null
+++ b/pkg/unmodifiable_collection/test/unmodifiable_collection_test.dart
@@ -0,0 +1,629 @@
+// 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:unmodifiable_collection/unmodifiable_collection.dart";
+import "package:unittest/unittest.dart";
+
+// Test unmodifiable collection views.
+// The collections should pass through the operations that are allowed,
+// an throw on the ones that aren't without affecting the original.
+
+main() {
+  List list = [];
+  testUnmodifiableList(list, new UnmodifiableListView(list), "empty");
+  list = [42];
+  testUnmodifiableList(list, new UnmodifiableListView(list), "single-42");
+  list = [7];
+  testUnmodifiableList(list, new UnmodifiableListView(list), "single!42");
+  list = [1, 42, 10];
+  testUnmodifiableList(list, new UnmodifiableListView(list), "three-42");
+  list = [1, 7, 10];
+  testUnmodifiableList(list, new UnmodifiableListView(list), "three!42");
+
+  list = [];
+  testNonGrowableList(list, new NonGrowableListView(list), "empty");
+  list = [42];
+  testNonGrowableList(list, new NonGrowableListView(list), "single-42");
+  list = [7];
+  testNonGrowableList(list, new NonGrowableListView(list), "single!42");
+  list = [1, 42, 10];
+  testNonGrowableList(list, new NonGrowableListView(list), "three-42");
+  list = [1, 7, 10];
+  testNonGrowableList(list, new NonGrowableListView(list), "three!42");
+
+  Set aSet = new Set();
+  testUnmodifiableSet(aSet, new UnmodifiableSetView(aSet), "empty");
+  aSet = new Set.from([42]);
+  testUnmodifiableSet(aSet, new UnmodifiableSetView(aSet), "single-42");
+  aSet = new Set.from([7]);
+  testUnmodifiableSet(aSet, new UnmodifiableSetView(aSet), "single!42");
+  aSet = new Set.from([1, 42, 10]);
+  testUnmodifiableSet(aSet, new UnmodifiableSetView(aSet), "three-42");
+  aSet = new Set.from([1, 7, 10]);
+  testUnmodifiableSet(aSet, new UnmodifiableSetView(aSet), "three!42");
+
+  Map map = new Map();
+  testUnmodifiableMap(map, new UnmodifiableMapView(map), "empty");
+  map = new Map()..[0] = 2;
+  testUnmodifiableMap(map, new UnmodifiableMapView(map), "single-0");
+  map = new Map()..[3] = 2;
+  testUnmodifiableMap(map, new UnmodifiableMapView(map), "single!0");
+  map = new Map()..[0] = 2
+                 ..[1] = 1
+                 ..[2] = 0;
+  testUnmodifiableMap(map, new UnmodifiableMapView(map), "three-0");
+  map = new Map()..[3] = 2
+                 ..[1] = 1
+                 ..[2] = 3;
+  testUnmodifiableMap(map, new UnmodifiableMapView(map), "three!0");
+}
+
+void testUnmodifiableList(List original, List wrapped, String name) {
+  name = "unmodifiable-list-$name";
+  testIterable(original, wrapped, name);
+  testReadList(original, wrapped, name);
+  testNoWriteList(original, wrapped, name);
+  testNoChangeLengthList(original, wrapped, name);
+}
+
+void testNonGrowableList(List original, List wrapped, String name) {
+  name = "nongrowable-list-$name";
+  testIterable(original, wrapped, name);
+  testReadList(original, wrapped, name);
+  testWriteList(original, wrapped, name);
+  testNoChangeLengthList(original, wrapped, name);
+}
+
+void testUnmodifiableSet(Set original, Set wrapped, String name) {
+  name = "unmodifiable-set-$name";
+  testIterable(original, wrapped, name);
+  testReadSet(original, wrapped, name);
+  testNoChangeSet(original, wrapped, name);
+}
+
+void testUnmodifiableMap(Map original, Map wrapped, name) {
+  name = "unmodifiable-map-$name";
+  testReadMap(original, wrapped, name);
+  testNoChangeMap(original, wrapped, name);
+}
+
+void testIterable(Iterable original, Iterable wrapped, String name) {
+  test("$name - any", () {
+    expect(wrapped.any((x) => true), equals(original.any((x) => true)));
+    expect(wrapped.any((x) => false), equals(original.any((x) => false)));
+  });
+
+  test("$name - contains", () {
+    expect(wrapped.contains(0), equals(original.contains(0)));
+  });
+
+  test("$name - elementAt", () {
+    if (original.isEmpty) {
+      expect(() => wrapped.elementAt(0), throws);
+    } else {
+      expect(wrapped.elementAt(0), equals(original.elementAt(0)));
+    }
+  });
+
+  test("$name - every", () {
+    expect(wrapped.every((x) => true), equals(original.every((x) => true)));
+    expect(wrapped.every((x) => false), equals(original.every((x) => false)));
+  });
+
+  test("$name - expand", () {
+    expect(wrapped.expand((x) => [x, x]),
+           equals(original.expand((x) => [x, x])));
+  });
+
+  test("$name - first", () {
+    if (original.isEmpty) {
+      expect(() => wrapped.first, throws);
+    } else {
+      expect(wrapped.first, equals(original.first));
+    }
+  });
+
+  test("$name - firstWhere", () {
+    if (original.isEmpty) {
+      expect(() => wrapped.firstWhere((_) => true), throws);
+    } else {
+      expect(wrapped.firstWhere((_) => true),
+             equals(original.firstWhere((_) => true)));
+    }
+    expect(() => wrapped.firstWhere((_) => false), throws);
+  });
+
+  test("$name - fold", () {
+    expect(wrapped.fold(0, (x, y) => x + y),
+           equals(original.fold(0, (x, y) => x + y)));
+  });
+
+  test("$name - forEach", () {
+    int wrapCtr = 0;
+    int origCtr = 0;
+    wrapped.forEach((x) { wrapCtr += x; });
+    original.forEach((x) { origCtr += x; });
+    expect(wrapCtr, equals(origCtr));
+  });
+
+  test("$name - isEmpty", () {
+    expect(wrapped.isEmpty, equals(original.isEmpty));
+  });
+
+  test("$name - isNotEmpty", () {
+    expect(wrapped.isNotEmpty, equals(original.isNotEmpty));
+  });
+
+  test("$name - iterator", () {
+    Iterator wrapIter = wrapped.iterator;
+    Iterator origIter = original.iterator;
+    while (origIter.moveNext()) {
+      expect(wrapIter.moveNext(), equals(true));
+      expect(wrapIter.current, equals(origIter.current));
+    }
+    expect(wrapIter.moveNext(), equals(false));
+  });
+
+  test("$name - join", () {
+    expect(wrapped.join(""), equals(original.join("")));
+    expect(wrapped.join("-"), equals(original.join("-")));
+  });
+
+  test("$name - last", () {
+    if (original.isEmpty) {
+      expect(() => wrapped.last, throws);
+    } else {
+      expect(wrapped.last, equals(original.last));
+    }
+  });
+
+  test("$name - lastWhere", () {
+    if (original.isEmpty) {
+      expect(() => wrapped.lastWhere((_) => true), throws);
+    } else {
+      expect(wrapped.lastWhere((_) => true),
+             equals(original.lastWhere((_) => true)));
+    }
+    expect(() => wrapped.lastWhere((_) => false), throws);
+  });
+
+  test("$name - length", () {
+    expect(wrapped.length, equals(original.length));
+  });
+
+  test("$name - map", () {
+    expect(wrapped.map((x) => "[$x]"),
+           equals(original.map((x) => "[$x]")));
+  });
+
+  test("$name - reduce", () {
+    if (original.isEmpty) {
+      expect(() => wrapped.reduce((x, y) => x + y), throws);
+    } else {
+      expect(wrapped.reduce((x, y) => x + y),
+             equals(original.reduce((x, y) => x + y)));
+    }
+  });
+
+  test("$name - single", () {
+    if (original.length != 1) {
+      expect(() => wrapped.single, throws);
+    } else {
+      expect(wrapped.single, equals(original.single));
+    }
+  });
+
+  test("$name - singleWhere", () {
+    if (original.length != 1) {
+      expect(() => wrapped.singleWhere((_) => true), throws);
+    } else {
+      expect(wrapped.singleWhere((_) => true),
+             equals(original.singleWhere((_) => true)));
+    }
+    expect(() => wrapped.singleWhere((_) => false), throws);
+  });
+
+  test("$name - skip", () {
+    expect(wrapped.skip(0), equals(original.skip(0)));
+    expect(wrapped.skip(1), equals(original.skip(1)));
+    expect(wrapped.skip(5), equals(original.skip(5)));
+  });
+
+  test("$name - skipWhile", () {
+    expect(wrapped.skipWhile((x) => true),
+           equals(original.skipWhile((x) => true)));
+    expect(wrapped.skipWhile((x) => false),
+           equals(original.skipWhile((x) => false)));
+    expect(wrapped.skipWhile((x) => x != 42),
+           equals(original.skipWhile((x) => x != 42)));
+  });
+
+  test("$name - take", () {
+    expect(wrapped.take(0), equals(original.take(0)));
+    expect(wrapped.take(1), equals(original.take(1)));
+    expect(wrapped.take(5), equals(original.take(5)));
+  });
+
+  test("$name - takeWhile", () {
+    expect(wrapped.takeWhile((x) => true),
+           equals(original.takeWhile((x) => true)));
+    expect(wrapped.takeWhile((x) => false),
+           equals(original.takeWhile((x) => false)));
+    expect(wrapped.takeWhile((x) => x != 42),
+           equals(original.takeWhile((x) => x != 42)));
+  });
+
+  test("$name - toList", () {
+    expect(wrapped.toList(), equals(original.toList()));
+    expect(wrapped.toList(growable: false),
+           equals(original.toList(growable: false)));
+  });
+
+  test("$name - toSet", () {
+    expect(wrapped.toSet(), equals(original.toSet()));
+  });
+
+  test("$name - where", () {
+    expect(wrapped.where((x) => true),
+           equals(original.where((x) => true)));
+    expect(wrapped.where((x) => false),
+           equals(original.where((x) => false)));
+    expect(wrapped.where((x) => x != 42),
+           equals(original.where((x) => x != 42)));
+  });
+}
+
+void testReadList(List original, List wrapped, String name) {
+  test("$name - length", () {
+    expect(wrapped.length, equals(original.length));
+  });
+
+  test("$name - isEmpty", () {
+    expect(wrapped.isEmpty, equals(original.isEmpty));
+  });
+
+  test("$name - isNotEmpty", () {
+    expect(wrapped.isNotEmpty, equals(original.isNotEmpty));
+  });
+
+  test("$name - []", () {
+    if (original.isEmpty) {
+      expect(() { wrapped[0]; }, throwsRangeError);
+    } else {
+      expect(wrapped[0], equals(original[0]));
+    }
+  });
+
+  test("$name - indexOf", () {
+    expect(wrapped.indexOf(42), equals(original.indexOf(42)));
+  });
+
+  test("$name - lastIndexOf", () {
+    expect(wrapped.lastIndexOf(42), equals(original.lastIndexOf(42)));
+  });
+
+  test("$name - getRange", () {
+    int len = original.length;
+    expect(wrapped.getRange(0, len), equals(original.getRange(0, len)));
+    expect(wrapped.getRange(len ~/ 2, len),
+           equals(original.getRange(len ~/ 2, len)));
+    expect(wrapped.getRange(0, len ~/ 2),
+           equals(original.getRange(0, len ~/ 2)));
+  });
+
+  test("$name - sublist", () {
+    int len = original.length;
+    expect(wrapped.sublist(0), equals(original.sublist(0)));
+    expect(wrapped.sublist(len ~/ 2), equals(original.sublist(len ~/ 2)));
+    expect(wrapped.sublist(0, len ~/ 2),
+           equals(original.sublist(0, len ~/ 2)));
+  });
+
+  test("$name - asMap", () {
+    expect(wrapped.asMap(), equals(original.asMap()));
+  });
+}
+
+void testNoWriteList(List original, List wrapped, String name) {
+  List copy = new List.from(original);
+
+  testThrows(name, thunk) {
+    test(name, () {
+      expect(thunk, throwsUnsupportedError);
+      // No modifications happened.
+      expect(original, equals(copy));
+    });
+  }
+
+  testThrows("$name - []= throws", () { wrapped[0] = 42; });
+
+  testThrows("$name - sort throws", () { wrapped.sort(); });
+
+  testThrows("$name - fillRange throws", () {
+    wrapped.fillRange(0, wrapped.length, 42);
+  });
+
+  testThrows("$name - setRange throws", () {
+      wrapped.setRange(0, wrapped.length,
+                    new Iterable.generate(wrapped.length, (i) => i));
+  });
+
+  testThrows("$name - setAll throws", () {
+      wrapped.setAll(0, new Iterable.generate(wrapped.length, (i) => i));
+  });
+}
+
+void testWriteList(List original, List wrapped, String name) {
+  List copy = new List.from(original);
+
+  test("$name - []=", () {
+    if (original.isNotEmpty) {
+      int originalFirst = original[0];
+      wrapped[0] = originalFirst + 1;
+      expect(original[0], equals(originalFirst + 1));
+      original[0] = originalFirst;
+    } else {
+      expect(() { wrapped[0] = 42; }, throws);
+    }
+  });
+
+  test("$name - sort", () {
+    List sortCopy = new List.from(original);
+    sortCopy.sort();
+    wrapped.sort();
+    expect(original, equals(sortCopy));
+    original.setAll(0, copy);
+  });
+
+  test("$name - fillRange", () {
+    wrapped.fillRange(0, wrapped.length, 37);
+    for (int i = 0; i < original.length; i++) {
+      expect(original[i], equals(37));
+    }
+    original.setAll(0, copy);
+  });
+
+  test("$name - setRange", () {
+    List reverseList = original.reversed.toList();
+    wrapped.setRange(0, wrapped.length, reverseList);
+    expect(original, equals(reverseList));
+    original.setAll(0, copy);
+  });
+
+  test("$name - setAll", () {
+    List reverseList = original.reversed.toList();
+    wrapped.setAll(0, reverseList);
+    expect(original, equals(reverseList));
+    original.setAll(0, copy);
+  });
+}
+
+void testNoChangeLengthList(List original, List wrapped, String name) {
+  List copy = new List.from(original);
+
+  testThrows(name, thunk) {
+    test(name, () {
+      expect(thunk, throwsUnsupportedError);
+      // No modifications happened.
+      expect(original, equals(copy));
+    });
+  }
+
+  testThrows("$name - length= throws", () {
+    wrapped.length = 100;
+  });
+
+  testThrows("$name - add throws", () {
+    wrapped.add(42);
+  });
+
+  testThrows("$name - addAll throws", () {
+    wrapped.addAll([42]);
+  });
+
+  testThrows("$name - insert throws", () {
+    wrapped.insert(0, 42);
+  });
+
+  testThrows("$name - insertAll throws", () {
+    wrapped.insertAll(0, [42]);
+  });
+
+  testThrows("$name - remove throws", () {
+    wrapped.remove(42);
+  });
+
+  testThrows("$name - removeAt throws", () {
+    wrapped.removeAt(0);
+  });
+
+  testThrows("$name - removeLast throws", () {
+    wrapped.removeLast();
+  });
+
+  testThrows("$name - removeWhere throws", () {
+    wrapped.removeWhere((E element) => false);
+  });
+
+  testThrows("$name - retainWhere throws", () {
+    wrapped.retainWhere((E element) => true);
+  });
+
+  testThrows("$name - removeRange throws", () {
+    wrapped.removeRange(0, wrapped.length);
+  });
+
+  testThrows("$name - replaceRange throws", () {
+    wrapped.replaceRange(0, wrapped.length, [42]);
+  });
+
+  testThrows("$name - clear throws", () {
+    wrapped.clear();
+  });
+}
+
+void testReadSet(Set original, Set wrapped, String name) {
+  Set copy = new Set.from(original);
+
+  test("$name - containsAll", () {
+    expect(wrapped.containsAll(copy), isTrue);
+    expect(wrapped.containsAll(copy.toList()), isTrue);
+    expect(wrapped.containsAll([]), isTrue);
+    expect(wrapped.containsAll([42]), equals(original.containsAll([42])));
+  });
+
+  test("$name - intersection", () {
+    expect(wrapped.intersection(new Set()), isEmpty);
+    expect(wrapped.intersection(copy), equals(original));
+    expect(wrapped.intersection(new Set.from([42])),
+            new Set.from(original.contains(42) ? [42] : []));
+  });
+
+  test("$name - union", () {
+    expect(wrapped.union(new Set()), equals(original));
+    expect(wrapped.union(copy), equals(original));
+    expect(wrapped.union(new Set.from([42])),
+           equals(original.union(new Set.from([42]))));
+  });
+
+  test("$name - difference", () {
+    expect(wrapped.difference(new Set()), equals(original));
+    expect(wrapped.difference(copy), isEmpty);
+    expect(wrapped.difference(new Set.from([42])),
+           equals(original.difference(new Set.from([42]))));
+  });
+}
+
+void testNoChangeSet(Set original, Set wrapped, String name) {
+  Set copy = new Set.from(original);
+
+  testThrows(name, thunk) {
+    test(name, () {
+      expect(thunk, throwsUnsupportedError);
+      // No modifications happened.
+      expect(original, equals(copy));
+    });
+  }
+
+  testThrows("$name - add throws", () {
+    wrapped.add(42);
+  });
+
+  testThrows("$name - addAll throws", () {
+    wrapped.addAll([42]);
+  });
+
+  testThrows("$name - addAll empty throws", () {
+    wrapped.addAll([]);
+  });
+
+  testThrows("$name - remove throws", () {
+    wrapped.remove(42);
+  });
+
+  testThrows("$name - removeAll throws", () {
+    wrapped.removeAll([42]);
+  });
+
+  testThrows("$name - removeAll empty throws", () {
+    wrapped.removeAll([]);
+  });
+
+  testThrows("$name - retainAll throws", () {
+    wrapped.retainAll([42]);
+  });
+
+  testThrows("$name - removeWhere throws", () {
+    wrapped.removeWhere((_) => false);
+  });
+
+  testThrows("$name - retainWhere throws", () {
+    wrapped.retainWhere((_) => true);
+  });
+
+  testThrows("$name - clear throws", () {
+    wrapped.clear();
+  });
+}
+
+void testReadMap(Map original, Map wrapped, String name) {
+  test("$name length", () {
+    expect(wrapped.length, equals(original.length));
+  });
+
+  test("$name isEmpty", () {
+    expect(wrapped.isEmpty, equals(original.isEmpty));
+  });
+
+  test("$name isNotEmpty", () {
+    expect(wrapped.isNotEmpty, equals(original.isNotEmpty));
+  });
+
+  test("$name operator[]", () {
+    expect(wrapped[0], equals(original[0]));
+    expect(wrapped[999], equals(original[999]));
+  });
+
+  test("$name containsKey", () {
+    expect(wrapped.containsKey(0), equals(original.containsKey(0)));
+    expect(wrapped.containsKey(999), equals(original.containsKey(999)));
+  });
+
+  test("$name containsValue", () {
+    expect(wrapped.containsValue(0), equals(original.containsValue(0)));
+    expect(wrapped.containsValue(999), equals(original.containsValue(999)));
+  });
+
+  test("$name forEach", () {
+    int origCnt = 0;
+    int wrapCnt = 0;
+    wrapped.forEach((k, v) { wrapCnt += 1 << k + 3 * v; });
+    original.forEach((k, v) { origCnt += 1 << k + 3 * v; });
+    expect(wrapCnt, equals(origCnt));
+  });
+
+  test("$name keys", () {
+    expect(wrapped.keys, equals(original.keys));
+  });
+
+  test("$name values", () {
+    expect(wrapped.values, equals(original.values));
+  });
+}
+
+testNoChangeMap(Map original, Map wrapped, String name) {
+  Map copy = new Map.from(original);
+
+  testThrows(name, thunk) {
+    test(name, () {
+      expect(thunk, throwsUnsupportedError);
+      // No modifications happened.
+      expect(original, equals(copy));
+    });
+  }
+
+ testThrows("$name operator[]= throws", () {
+   wrapped[0] = 42;
+ });
+
+ testThrows("$name putIfAbsent throws", () {
+   wrapped.putIfAbsent(0, () => 42);
+ });
+
+ testThrows("$name addAll throws", () {
+   wrapped.addAll(new Map()..[42] = 42);
+ });
+
+ testThrows("$name addAll empty throws", () {
+   wrapped.addAll(new Map());
+ });
+
+ testThrows("$name remove throws", () {
+   wrapped.remove(0);
+ });
+
+ testThrows("$name clear throws", () {
+   wrapped.clear();
+ });
+}
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 22db244..099f6a0 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -4,13 +4,7 @@
 
 {
   'variables': {
-    # We place most generated source files in LIB_DIR (rather than, say
-    # SHARED_INTERMEDIATE_DIR) because it is toolset specific. This avoids
-    # two problems. First, if a generated source file has architecture specific
-    # code, we'll get two different files in two different directories. Second,
-    # if a generated source file is needed to build a target with multiple
-    # toolsets, we avoid having duplicate Makefile targets.
-    'gen_source_dir': '<(LIB_DIR)',
+    'gen_source_dir': '<(SHARED_INTERMEDIATE_DIR)',
 
     'io_cc_file': '<(gen_source_dir)/io_gen.cc',
     'io_patch_cc_file': '<(gen_source_dir)/io_patch_gen.cc',
@@ -19,17 +13,13 @@
     'snapshot_in_cc_file': 'snapshot_in.cc',
     'snapshot_bin_file': '<(gen_source_dir)/snapshot_gen.bin',
     'resources_cc_file': '<(gen_source_dir)/resources_gen.cc',
-
-    # The program that creates snapshot_gen.cc is only built and run on the
-    # host, but it must be available when dart is built for the target. Thus,
-    # we keep it in a shared location.
-    'snapshot_cc_file': '<(SHARED_INTERMEDIATE_DIR)/snapshot_gen.cc',
+    'snapshot_cc_file': '<(gen_source_dir)/snapshot_gen.cc',
   },
   'targets': [
     {
       'target_name': 'generate_builtin_cc_file',
       'type': 'none',
-      'toolsets':['target','host'],
+      'toolsets':['host'],
       'includes': [
         'builtin_sources.gypi',
       ],
@@ -61,7 +51,7 @@
     {
       'target_name': 'generate_io_cc_file',
       'type': 'none',
-      'toolsets':['target','host'],
+      'toolsets':['host'],
       'sources': [
         '../../sdk/lib/io/io.dart',
       ],
@@ -96,7 +86,7 @@
     {
       'target_name': 'generate_io_patch_cc_file',
       'type': 'none',
-      'toolsets':['target','host'],
+      'toolsets':['host'],
       'includes': [
         'io_sources.gypi',
       ],
@@ -130,9 +120,9 @@
       'type': 'static_library',
       'toolsets':['target','host'],
       'dependencies': [
-        'generate_builtin_cc_file',
-        'generate_io_cc_file',
-        'generate_io_patch_cc_file',
+        'generate_builtin_cc_file#host',
+        'generate_io_cc_file#host',
+        'generate_io_patch_cc_file#host',
       ],
       'include_dirs': [
         '..',
@@ -198,6 +188,9 @@
           ],
         }],
         ['OS=="win"', {
+          'link_settings': {
+            'libraries': [ '-liphlpapi.lib' ],
+          },
           # TODO(antonm): fix the implementation.
           # Current implementation accepts char* strings
           # and therefore fails to compile once _UNICODE is
@@ -222,7 +215,7 @@
         'libdart_vm',
         'libjscre',
         'libdouble_conversion',
-        'generate_version_cc_file',
+        'generate_version_cc_file#host',
       ],
       'include_dirs': [
         '..',
@@ -342,6 +335,7 @@
     {
       'target_name': 'generate_resources_cc_file',
       'type': 'none',
+      'toolsets':['host'],
       'includes': [
         'vmstats_sources.gypi',
       ],
@@ -375,7 +369,7 @@
         'libdart_builtin',
         'libdart_io',
         'generate_snapshot_file#host',
-        'generate_resources_cc_file',
+        'generate_resources_cc_file#host',
       ],
       'include_dirs': [
         '..',
@@ -443,7 +437,7 @@
         'libdart_withcore',
         'libdart_builtin',
         'libdart_io',
-        'generate_resources_cc_file',
+        'generate_resources_cc_file#host',
       ],
       'include_dirs': [
         '..',
@@ -524,7 +518,7 @@
         'libdart_builtin',
         'libdart_io',
         'generate_snapshot_file#host',
-        'generate_snapshot_test_dat_file',
+        'generate_snapshot_test_dat_file#host',
       ],
       'include_dirs': [
         '..',
@@ -595,7 +589,7 @@
         'libdart_builtin',
         'libdart_io',
         'generate_snapshot_file#host',
-        'generate_snapshot_test_dat_file',
+        'generate_snapshot_test_dat_file#host',
       ],
       'include_dirs': [
         '..',
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index 716ec71..818acaf 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -5,28 +5,56 @@
 library builtin;
 import 'dart:io';
 
-int _httpRequestResponseCode = 0;
-String _httpRequestStatusString;
+// Corelib 'print' implementation.
+void _print(arg) {
+  _Logger._printString(arg.toString());
+}
+
+
+class _Logger {
+  static void _printString(String s) native "Logger_PrintString";
+}
+
+
+_getPrintClosure() => _print;
+
+
+void _logResolution(String msg) {
+  final enabled = false;
+  if (enabled) {
+    _Logger._printString(msg);
+  }
+}
+
+
+var _httpRequestResponseCode = 0;
+var _httpRequestStatusString;
 var _httpRequestResponse;
 
+_getHttpRequestResponseCode() => _httpRequestResponseCode;
+_getHttpRequestStatusString() => _httpRequestStatusString;
+_getHttpRequestResponse() => _httpRequestResponse;
+
 void _requestCompleted(HttpClientResponseBody body) {
   _httpRequestResponseCode = body.statusCode;
   _httpRequestStatusString = '${body.statusCode} ${body.reasonPhrase}';
   _httpRequestResponse = null;
-  if (body.statusCode != 200 || body.type == "json") {
+  if (body.statusCode != 200 || body.type == 'json') {
     return;
   }
   _httpRequestResponse = body.body;
 }
 
+
 void _requestFailed(error) {
   _httpRequestResponseCode = 0;
   _httpRequestStatusString = error.toString();
   _httpRequestResponse = null;
 }
 
-HttpClient _client = new HttpClient();
+
 void _makeHttpRequest(String uri) {
+  var _client = new HttpClient();
   _httpRequestResponseCode = 0;
   _httpRequestStatusString = null;
   _httpRequestResponse = null;
@@ -41,76 +69,94 @@
       });
 }
 
-// Corelib 'print' implementation.
-void _print(arg) {
-  _Logger._printString(arg.toString());
-}
 
-class _Logger {
-  static void _printString(String s) native "Logger_PrintString";
-}
-
-_getPrintClosure() => _print;
-
-// The URI that the entrypoint script was loaded from. Remembered so that
+// Are we running on Windows?
+var _isWindows = false;
+// The current working directory
+var _workingDirectoryUri;
+// The URI that the entry point script was loaded from. Remembered so that
 // package imports can be resolved relative to it.
-var _entrypoint;
-
+var _entryPointScript;
 // The directory to look in to resolve "package:" scheme URIs.
 var _packageRoot;
 
-void _logResolution(String msg) {
-  final enabled = false;
-  if (enabled) {
-    _Logger._printString(msg);
-  }
+
+void _setWindows() {
+  _isWindows = true;
 }
 
+
+_sanitizeWindowsPath(path) {
+  // For Windows we need to massage the paths a bit according to
+  // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
+  //
+  // Convert
+  // C:\one\two\three
+  // to
+  // /C:/one/two/three
+
+  if (_isWindows == false) {
+    // Do nothing when not running Windows.
+    return path;
+  }
+
+  var fixedPath = "${path.replaceAll('\\', '/')}";
+
+  if ((path.length > 2) && (path[1] == ':')) {
+    // Path begins with a drive letter.
+    return '/$fixedPath';
+  }
+
+  return fixedPath;
+}
+
+_enforceTrailingSlash(uri) {
+  // Ensure we have a trailing slash character.
+  if (!uri.endsWith('/')) {
+    return '$uri/';
+  }
+  return uri;
+}
+
+
+void _setWorkingDirectory(cwd) {
+  cwd = _sanitizeWindowsPath(cwd);
+  cwd = _enforceTrailingSlash(cwd);
+  _workingDirectoryUri = new Uri(scheme: 'file', path: cwd);
+  _logResolution('# Working Directory: $cwd');
+}
+
+
 _setPackageRoot(String packageRoot) {
-  // TODO(mattsh) - refactor windows drive and path handling code
-  // so it can be used here if needed.
-  _packageRoot = packageRoot;
+  packageRoot = _enforceTrailingSlash(packageRoot);
+  _packageRoot = _workingDirectoryUri.resolve(packageRoot);
+  _logResolution('# Package root: $packageRoot -> $_packageRoot');
 }
 
-String _resolveScriptUri(String cwd, String scriptName, bool isWindows) {
+
+String _resolveScriptUri(String scriptName) {
+  if (_workingDirectoryUri == null) {
+    throw 'No current working directory set.';
+  }
+  scriptName = _sanitizeWindowsPath(scriptName);
+
   var scriptUri = Uri.parse(scriptName);
-  if (scriptUri.scheme == 'http') {
-    _entrypoint = scriptUri;
-    _logResolution("# Resolved script to: $_entrypoint");
-    return _entrypoint.toString();
+  if (scriptUri.scheme != '') {
+    // Script has a scheme, assume that it is fully formed.
+    _entryPointScript = scriptUri;
+  } else {
+    // Script does not have a scheme, assume that it is a path,
+    // resolve it against the working directory.
+    _entryPointScript = _workingDirectoryUri.resolve(scriptName);
   }
-  _logResolution("# Current working directory: $cwd");
-  _logResolution("# ScriptName: $scriptName");
-  if (isWindows) {
-    // For Windows we need to massage the paths a bit according to
-    // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
-    //
-    // Convert
-    // C:\one\two\three
-    // to
-    // /C:/one/two/three
-    cwd = "/${cwd.replaceAll('\\', '/')}";
-    _logResolution("## cwd: $cwd");
-    if ((scriptName.length > 2) && (scriptName[1] == ":")) {
-      // This is an absolute path.
-      scriptName = "/${scriptName.replaceAll('\\', '/')}";
-    } else {
-      scriptName = scriptName.replaceAll('\\', '/');
-    }
-    _logResolution("## scriptName: $scriptName");
-  }
-  var base =
-      new Uri(scheme: "file",
-              path: cwd.endsWith("/") ? cwd : "$cwd/");
-  _entrypoint = base.resolve(scriptName);
-  _logResolution("# Resolved script to: $_entrypoint");
-
-  return _entrypoint.toString();
+  _logResolution('# Resolved entry point to: $_entryPointScript');
+  return _entryPointScript.toString();
 }
 
+
 String _resolveUri(String base, String userString) {
   var baseUri = Uri.parse(base);
-  _logResolution("# Resolving: $userString from $base");
+  _logResolution('# Resolving: $userString from $base');
 
   var uri = Uri.parse(userString);
   var resolved;
@@ -125,18 +171,18 @@
       // package URI path part.
       path = _filePathFromPackageUri(resolved);
     }
-    resolved = new Uri(scheme: "dart-ext", path: path);
+    resolved = new Uri(scheme: 'dart-ext', path: path);
   } else {
     resolved = baseUri.resolve(userString);
   }
-  _logResolution("# Resolved to: $resolved");
+  _logResolution('# Resolved to: $resolved');
   return resolved.toString();
 }
 
 
-String _filePathFromUri(String userUri, bool isWindows) {
+String _filePathFromUri(String userUri) {
   var uri = Uri.parse(userUri);
-  _logResolution("# Getting file path from: $uri");
+  _logResolution('# Getting file path from: $uri');
 
   var path;
   switch (uri.scheme) {
@@ -154,40 +200,43 @@
       break;
     default:
       // Only handling file and package URIs in standalone binary.
-      _logResolution("# Unknown scheme (${uri.scheme}) in $uri.");
-      throw "Not a known scheme: $uri";
+      _logResolution('# Unknown scheme (${uri.scheme}) in $uri.');
+      throw 'Not a known scheme: $uri';
   }
 
-  if (isWindows && path.startsWith("/")) {
+  if (_isWindows && path.startsWith('/')) {
     // For Windows we need to massage the paths a bit according to
     // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
     //
     // Drop the leading / before the drive letter.
     path = path.substring(1);
-    _logResolution("# path: $path");
+    _logResolution('# Path: Removed leading / -> $path');
   }
 
   return path;
 }
 
+
 String _filePathFromFileUri(Uri uri) {
   if (!uri.host.isEmpty) {
     throw "URIs using the 'file:' scheme may not contain a host.";
   }
 
-  _logResolution("# Path: ${uri.path}");
+  _logResolution('# Path: $uri -> ${uri.path}');
   return uri.path;
 }
 
+
 String _filePathFromOtherUri(Uri uri) {
   if (!uri.host.isEmpty) {
-    throw "URIs whose paths are used as file paths may not contain a host.";
+    throw 'URIs whose paths are used as file paths may not contain a host.';
   }
 
-  _logResolution("# Path: ${uri.path}");
+  _logResolution('# Path: $uri -> ${uri.path}');
   return uri.path;
 }
 
+
 String _filePathFromPackageUri(Uri uri) {
   if (!uri.host.isEmpty) {
     var path = (uri.path != '') ? '${uri.host}${uri.path}' : uri.host;
@@ -198,22 +247,27 @@
           "'$right', not '$wrong'.";
   }
 
+  var packageUri;
   var path;
   if (_packageRoot != null) {
-    path = "${_packageRoot}${uri.path}";
+    // Resolve against package root.
+    packageUri = _packageRoot.resolve(uri.path);
   } else {
-    if (_entrypoint.scheme == 'http') {
-      path = _entrypoint.resolve('packages/${uri.path}').toString();
-    } else {
-      path = _entrypoint.resolve('packages/${uri.path}').path;
-    }
+    // Resolve against working directory.
+    packageUri = _entryPointScript.resolve('packages/${uri.path}');
   }
 
-  _logResolution("# Package: $path");
+  if (packageUri.scheme == 'file') {
+    path = packageUri.path;
+  } else {
+    path = packageUri.toString();
+  }
+  _logResolution('# Package: $uri -> $path');
   return path;
 }
 
+
 String _filePathFromHttpUri(Uri uri) {
-  _logResolution('# Path: $uri');
+  _logResolution('# Path: $uri -> $uri');
   return uri.toString();
 }
diff --git a/runtime/bin/common.cc b/runtime/bin/common.cc
index fd6386e..ce9a9ef 100644
--- a/runtime/bin/common.cc
+++ b/runtime/bin/common.cc
@@ -58,12 +58,5 @@
   Dart_ExitScope();
 }
 
-
-void FUNCTION_NAME(Common_GetVersion)(Dart_NativeArguments args) {
-  Dart_EnterScope();
-  Dart_SetReturnValue(args, Dart_NewStringFromCString(Dart_VersionString()));
-  Dart_ExitScope();
-}
-
 }  // namespace bin
 }  // namespace dart
diff --git a/runtime/bin/common_patch.dart b/runtime/bin/common_patch.dart
index e1d36f4..8b77d3a 100644
--- a/runtime/bin/common_patch.dart
+++ b/runtime/bin/common_patch.dart
@@ -11,7 +11,3 @@
   /* patch */ static Uint8List getRandomBytes(int count)
       native "Crypto_GetRandomBytes";
 }
-
-patch class _OptionsImpl {
-  /* patch */ String get version native "Common_GetVersion";
-}
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 8134848..3e107f8 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -243,8 +243,8 @@
 }
 
 
-static Dart_Handle SingleArgDart_Invoke(Dart_Handle arg, Dart_Handle lib,
-                                        const char* method) {
+static Dart_Handle SingleArgDart_Invoke(Dart_Handle lib, const char* method,
+                                        Dart_Handle arg) {
   const int kNumArgs = 1;
   Dart_Handle dart_args[kNumArgs];
   dart_args[0] = arg;
@@ -253,10 +253,10 @@
 
 
 // TODO(iposva): Allocate from the zone instead of leaking error string
-// here. On the other hand the binary is about the exit anyway.
+// here. On the other hand the binary is about to exit anyway.
 #define SET_ERROR_MSG(error_msg, format, ...)                                  \
   intptr_t len = snprintf(NULL, 0, format, __VA_ARGS__);                       \
-  char *msg = reinterpret_cast<char*>(malloc(len + 1));                        \
+  char* msg = reinterpret_cast<char*>(malloc(len + 1));                        \
   snprintf(msg, len + 1, format, __VA_ARGS__);                                 \
   *error_msg = msg
 
@@ -267,19 +267,27 @@
   ASSERT(buffer != NULL);
   ASSERT(buffer_len != NULL);
   ASSERT(!Dart_HasLivePorts());
-  SingleArgDart_Invoke(uri, builtin_lib, "_makeHttpRequest");
+  SingleArgDart_Invoke(builtin_lib, "_makeHttpRequest", uri);
   // Run until all ports to isolate are closed.
   Dart_Handle result = Dart_RunLoop();
   if (Dart_IsError(result)) {
     return result;
   }
-  intptr_t responseCode =
-    DartUtils::GetIntegerField(builtin_lib, "_httpRequestResponseCode");
+  result = Dart_Invoke(builtin_lib,
+                       DartUtils::NewString("_getHttpRequestResponseCode"),
+                       0,
+                       NULL);
+  if (Dart_IsError(result)) {
+    return result;
+  }
+  intptr_t responseCode = DartUtils::GetIntegerValue(result);
   if (responseCode != HttpResponseCodeOK) {
     // Return error.
     Dart_Handle responseStatus =
-        Dart_GetField(builtin_lib,
-                      DartUtils::NewString("_httpRequestStatusString"));
+        Dart_Invoke(builtin_lib,
+                    DartUtils::NewString("_getHttpRequestStatusString"),
+                    0,
+                    NULL);
     if (Dart_IsError(responseStatus)) {
       return responseStatus;
     }
@@ -289,7 +297,8 @@
     return Dart_Error(DartUtils::GetStringValue(responseStatus));
   }
   Dart_Handle response =
-    Dart_GetField(builtin_lib, DartUtils::NewString("_httpRequestResponse"));
+      Dart_Invoke(builtin_lib, DartUtils::NewString("_getHttpRequestResponse"),
+                  0, NULL);
   if (Dart_IsError(response)) {
     return response;
   }
@@ -384,13 +393,17 @@
 }
 
 
+Dart_Handle DartUtils::SetWorkingDirectory(Dart_Handle builtin_lib) {
+  Dart_Handle directory = NewString(original_working_directory);
+  return SingleArgDart_Invoke(builtin_lib, "_setWorkingDirectory", directory);
+}
+
+
 Dart_Handle DartUtils::ResolveScriptUri(Dart_Handle script_uri,
                                         Dart_Handle builtin_lib) {
-  const int kNumArgs = 3;
+  const int kNumArgs = 1;
   Dart_Handle dart_args[kNumArgs];
-  dart_args[0] = NewString(original_working_directory);
-  dart_args[1] = script_uri;
-  dart_args[2] = (IsWindowsHost() ? Dart_True() : Dart_False());
+  dart_args[0] = script_uri;
   return Dart_Invoke(builtin_lib,
                      NewString("_resolveScriptUri"),
                      kNumArgs,
@@ -400,10 +413,9 @@
 
 Dart_Handle DartUtils::FilePathFromUri(Dart_Handle script_uri,
                                        Dart_Handle builtin_lib) {
-  const int kNumArgs = 2;
+  const int kNumArgs = 1;
   Dart_Handle dart_args[kNumArgs];
   dart_args[0] = script_uri;
-  dart_args[1] = (IsWindowsHost() ? Dart_True() : Dart_False());
   return Dart_Invoke(builtin_lib,
                      NewString("_filePathFromUri"),
                      kNumArgs,
@@ -564,9 +576,6 @@
 
 Dart_Handle DartUtils::LoadScript(const char* script_uri,
                                   Dart_Handle builtin_lib) {
-  // Always call ResolveScriptUri because as a side effect it sets
-  // the script entry path which is used when automatically resolving
-  // package root.
   Dart_Handle resolved_script_uri =
       ResolveScriptUri(NewString(script_uri), builtin_lib);
   if (Dart_IsError(resolved_script_uri)) {
@@ -647,7 +656,7 @@
                                                Dart_Handle builtin_lib) {
   // Setup the corelib 'print' function.
   Dart_Handle print = Dart_Invoke(
-      builtin_lib, NewString("_getPrintClosure"), 0, 0);
+      builtin_lib, NewString("_getPrintClosure"), 0, NULL);
   Dart_Handle corelib = Dart_LookupLibrary(NewString("dart:core"));
   Dart_Handle result = Dart_SetField(corelib,
                                      NewString("_printClosure"),
@@ -666,6 +675,21 @@
   DART_CHECK_VALID(Dart_Invoke(
       async_lib, NewString("_setTimerFactoryClosure"), 1, args));
 
+
+  if (IsWindowsHost()) {
+    // Set running on Windows flag.
+    result = Dart_Invoke(builtin_lib, NewString("_setWindows"), 0, NULL);
+    if (Dart_IsError(result)) {
+      return result;
+    }
+  }
+
+  // Set current working directory.
+  result = SetWorkingDirectory(builtin_lib);
+  if (Dart_IsError(result)) {
+    return result;
+  }
+
   // Set up package root if specified.
   if (package_root != NULL) {
     result = NewString(package_root);
@@ -737,10 +761,10 @@
 }
 
 
-Dart_Handle DartUtils::GetDartClass(const char* library_url,
-                                    const char* class_name) {
-  return Dart_GetClass(Dart_LookupLibrary(NewString(library_url)),
-                       NewString(class_name));
+Dart_Handle DartUtils::GetDartType(const char* library_url,
+                                   const char* class_name) {
+  return Dart_GetType(Dart_LookupLibrary(NewString(library_url)),
+                      NewString(class_name), 0, NULL);
 }
 
 
@@ -753,22 +777,24 @@
 
 Dart_Handle DartUtils::NewDartOSError(OSError* os_error) {
   // Create a dart:io OSError object with the information retrieved from the OS.
-  Dart_Handle clazz = GetDartClass(kIOLibURL, "OSError");
+  Dart_Handle type = GetDartType(kIOLibURL, "OSError");
   Dart_Handle args[2];
   args[0] = NewString(os_error->message());
   args[1] = Dart_NewInteger(os_error->code());
-  return Dart_New(clazz, Dart_Null(), 2, args);
+  return Dart_New(type, Dart_Null(), 2, args);
 }
 
 
-Dart_Handle DartUtils::NewDartSocketException(const char* message,
-                                              Dart_Handle os_error) {
-  // Create a dart:io SocketException object.
-  Dart_Handle clazz = GetDartClass(kIOLibURL, "SocketException");
+Dart_Handle DartUtils::NewDartExceptionWithOSError(const char* library_url,
+                                                   const char* exception_name,
+                                                   const char* message,
+                                                   Dart_Handle os_error) {
+  // Create a Dart Exception object with a message and an OSError.
+  Dart_Handle type = GetDartType(library_url, exception_name);
   Dart_Handle args[2];
   args[0] = NewString(message);
   args[1] = os_error;
-  return Dart_New(clazz, Dart_Null(), 2, args);
+  return Dart_New(type, Dart_Null(), 2, args);
 }
 
 
@@ -776,13 +802,13 @@
                                                    const char* exception_name,
                                                    const char* message) {
   // Create a Dart Exception object with a message.
-  Dart_Handle clazz = GetDartClass(library_url, exception_name);
+  Dart_Handle type = GetDartType(library_url, exception_name);
   if (message != NULL) {
     Dart_Handle args[1];
     args[0] = NewString(message);
-    return Dart_New(clazz, Dart_Null(), 1, args);
+    return Dart_New(type, Dart_Null(), 1, args);
   } else {
-    return Dart_New(clazz, Dart_Null(), 0, NULL);
+    return Dart_New(type, Dart_Null(), 0, NULL);
   }
 }
 
@@ -794,6 +820,17 @@
 }
 
 
+Dart_Handle DartUtils::NewDartIOException(const char* exception_name,
+                                          const char* message,
+                                          Dart_Handle os_error) {
+  // Create a dart:io exception object of the given type.
+  return NewDartExceptionWithOSError(kIOLibURL,
+                                     exception_name,
+                                     message,
+                                     os_error);
+}
+
+
 Dart_Handle DartUtils::NewInternalError(const char* message) {
   return NewDartExceptionWithMessage(kCoreLibURL, "InternalError", message);
 }
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 026b83a..85b5585 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -135,18 +135,23 @@
   static bool PostNull(Dart_Port port_id);
   static bool PostInt32(Dart_Port port_id, int32_t value);
 
-  static Dart_Handle GetDartClass(const char* library_url,
-                                  const char* class_name);
+  static Dart_Handle GetDartType(const char* library_url,
+                                 const char* class_name);
   // Create a new Dart OSError object with the current OS error.
   static Dart_Handle NewDartOSError();
   // Create a new Dart OSError object with the provided OS error.
   static Dart_Handle NewDartOSError(OSError* os_error);
-  static Dart_Handle NewDartSocketException(const char* message,
-                                            Dart_Handle os_error);
+  static Dart_Handle NewDartExceptionWithOSError(const char* library_url,
+                                                 const char* exception_name,
+                                                 const char* message,
+                                                 Dart_Handle os_error);
   static Dart_Handle NewDartExceptionWithMessage(const char* library_url,
                                                  const char* exception_name,
                                                  const char* message);
   static Dart_Handle NewDartArgumentError(const char* message);
+  static Dart_Handle NewDartIOException(const char* exception_name,
+                                        const char* message,
+                                        Dart_Handle os_error);
 
   // Create a new Dart String object from a C String.
   static Dart_Handle NewString(const char* str) {
@@ -163,6 +168,8 @@
   static const char* MapLibraryUrl(CommandLineOptions* url_mapping,
                                    const char* url_string);
 
+  static Dart_Handle SetWorkingDirectory(Dart_Handle builtin_lib);
+
   static Dart_Handle ResolveScriptUri(Dart_Handle script_uri,
                                       Dart_Handle builtin_lib);
 
diff --git a/runtime/bin/dbg_connection.cc b/runtime/bin/dbg_connection.cc
index 1d722b9..db77a16 100644
--- a/runtime/bin/dbg_connection.cc
+++ b/runtime/bin/dbg_connection.cc
@@ -300,9 +300,11 @@
   // debugger commands received on these connections.
   ASSERT(listener_fd_ == -1);
   OSError *os_error;
-  SocketAddresses* addresses = Socket::LookupAddress(address, -1, &os_error);
+  AddressList<SocketAddress>* addresses =
+      Socket::LookupAddress(address, -1, &os_error);
   listener_fd_ = ServerSocket::CreateBindListen(
       addresses->GetAt(0)->addr(), port_number, 1);
+  delete addresses;
   port_number = Socket::GetPort(listener_fd_);
   DebuggerConnectionImpl::StartHandler(port_number);
   return port_number;
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index 7ce1787..3d86916 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -146,7 +146,7 @@
   // Create the list to hold the directory listing here, and pass it to the
   // SyncDirectoryListing object, which adds elements to it.
   Dart_Handle results =
-      Dart_New(DartUtils::GetDartClass(DartUtils::kCoreLibURL, "List"),
+      Dart_New(DartUtils::GetDartType(DartUtils::kCoreLibURL, "List"),
                Dart_Null(),
                0,
                NULL);
@@ -413,7 +413,7 @@
 bool SyncDirectoryListing::HandleDirectory(char* dir_name) {
   Dart_Handle dir_name_dart = DartUtils::NewString(dir_name);
   Dart_Handle dir =
-      Dart_New(directory_class_, Dart_Null(), 1, &dir_name_dart);
+      Dart_New(directory_type_, Dart_Null(), 1, &dir_name_dart);
   Dart_Invoke(results_, add_string_, 1, &dir);
   return true;
 }
@@ -421,7 +421,7 @@
 bool SyncDirectoryListing::HandleLink(char* link_name) {
   Dart_Handle link_name_dart = DartUtils::NewString(link_name);
   Dart_Handle link =
-      Dart_New(link_class_, Dart_Null(), 1, &link_name_dart);
+      Dart_New(link_type_, Dart_Null(), 1, &link_name_dart);
   Dart_Invoke(results_, add_string_, 1, &link);
   return true;
 }
@@ -429,7 +429,7 @@
 bool SyncDirectoryListing::HandleFile(char* file_name) {
   Dart_Handle file_name_dart = DartUtils::NewString(file_name);
   Dart_Handle file =
-      Dart_New(file_class_, Dart_Null(), 1, &file_name_dart);
+      Dart_New(file_type_, Dart_Null(), 1, &file_name_dart);
   Dart_Invoke(results_, add_string_, 1, &file);
   return true;
 }
@@ -441,7 +441,7 @@
   args[1] = DartUtils::NewString(dir_name);
   args[2] = dart_os_error;
   Dart_ThrowException(Dart_New(
-      DartUtils::GetDartClass(DartUtils::kIOLibURL, "DirectoryException"),
+      DartUtils::GetDartType(DartUtils::kIOLibURL, "DirectoryException"),
       Dart_Null(),
       3,
       args));
diff --git a/runtime/bin/directory.h b/runtime/bin/directory.h
index 89ec90b..a8786bf 100644
--- a/runtime/bin/directory.h
+++ b/runtime/bin/directory.h
@@ -221,12 +221,12 @@
       : DirectoryListing(dir_name, recursive, follow_links),
         results_(results) {
     add_string_ = DartUtils::NewString("add");
-    directory_class_ =
-        DartUtils::GetDartClass(DartUtils::kIOLibURL, "Directory");
-    file_class_ =
-        DartUtils::GetDartClass(DartUtils::kIOLibURL, "File");
-    link_class_ =
-        DartUtils::GetDartClass(DartUtils::kIOLibURL, "Link");
+    directory_type_ =
+        DartUtils::GetDartType(DartUtils::kIOLibURL, "Directory");
+    file_type_ =
+        DartUtils::GetDartType(DartUtils::kIOLibURL, "File");
+    link_type_ =
+        DartUtils::GetDartType(DartUtils::kIOLibURL, "Link");
   }
   virtual ~SyncDirectoryListing() {}
   virtual bool HandleDirectory(char* dir_name);
@@ -237,9 +237,9 @@
  private:
   Dart_Handle results_;
   Dart_Handle add_string_;
-  Dart_Handle directory_class_;
-  Dart_Handle file_class_;
-  Dart_Handle link_class_;
+  Dart_Handle directory_type_;
+  Dart_Handle file_type_;
+  Dart_Handle link_type_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(SyncDirectoryListing);
 };
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index 87fc2c1..c687cde 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -1180,8 +1180,8 @@
 
 
 static void FileService(Dart_Port dest_port_id,
-                 Dart_Port reply_port_id,
-                 Dart_CObject* message) {
+                        Dart_Port reply_port_id,
+                        Dart_CObject* message) {
   CObject* response = CObject::IllegalArgumentError();
   CObjectArray request(message);
   if (message->type == Dart_CObject_kArray) {
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index e5172b7..163c4af 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -21,7 +21,6 @@
 // builtin_natives.cc instead.
 #define IO_NATIVE_LIST(V)                                                      \
   V(Common_IsBuiltinList, 1)                                                   \
-  V(Common_GetVersion, 1)                                                      \
   V(Crypto_GetRandomBytes, 1)                                                  \
   V(EventHandler_Start, 1)                                                     \
   V(EventHandler_SendData, 4)                                                  \
@@ -36,6 +35,7 @@
   V(Platform_PathSeparator, 0)                                                 \
   V(Platform_LocalHostname, 0)                                                 \
   V(Platform_Environment, 0)                                                   \
+  V(Platform_GetVersion, 0)                                                    \
   V(Process_Start, 10)                                                         \
   V(Process_Kill, 3)                                                           \
   V(Process_SetExitCode, 1)                                                    \
@@ -47,7 +47,6 @@
   V(Socket_CreateConnect, 3)                                                   \
   V(Socket_Available, 1)                                                       \
   V(Socket_Read, 2)                                                            \
-  V(Socket_ReadList, 4)                                                        \
   V(Socket_WriteList, 4)                                                       \
   V(Socket_GetPort, 1)                                                         \
   V(Socket_GetRemotePeer, 1)                                                   \
@@ -56,15 +55,16 @@
   V(Socket_NewServicePort, 0)                                                  \
   V(Socket_GetType, 1)                                                         \
   V(Socket_SetOption, 3)                                                       \
-  V(SecureSocket_Connect, 8)                                                   \
+  V(SecureSocket_Connect, 9)                                                   \
   V(SecureSocket_Destroy, 1)                                                   \
   V(SecureSocket_Handshake, 1)                                                 \
   V(SecureSocket_Init, 1)                                                      \
   V(SecureSocket_PeerCertificate, 1)                                           \
-  V(SecureSocket_ProcessBuffer, 2)                                             \
   V(SecureSocket_RegisterBadCertificateCallback, 2)                            \
   V(SecureSocket_RegisterHandshakeCompleteCallback, 2)                         \
   V(SecureSocket_InitializeLibrary, 3)                                         \
+  V(SecureSocket_NewServicePort, 0)                                            \
+  V(SecureSocket_FilterPointer, 1)                                             \
   V(StringToSystemEncoding, 1)                                                 \
   V(SystemEncodingToString, 1)
 
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 9081f70..18f7667 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -402,23 +402,21 @@
   if (Dart_IsError(io_lib)) {
     return io_lib;
   }
-  Dart_Handle runtime_options_class_name =
-      DartUtils::NewString("_OptionsImpl");
-  if (Dart_IsError(runtime_options_class_name)) {
-    return runtime_options_class_name;
+  Dart_Handle platform_class_name = DartUtils::NewString("Platform");
+  if (Dart_IsError(platform_class_name)) {
+    return platform_class_name;
   }
-  Dart_Handle runtime_options_class = Dart_GetClass(
-      io_lib, runtime_options_class_name);
-  if (Dart_IsError(runtime_options_class)) {
-    return runtime_options_class;
+  Dart_Handle platform_type =
+      Dart_GetType(io_lib, platform_class_name, 0, NULL);
+  if (Dart_IsError(platform_type)) {
+    return platform_type;
   }
-  Dart_Handle executable_name_name =
-      DartUtils::NewString("_nativeExecutable");
+  Dart_Handle executable_name_name = DartUtils::NewString("_nativeExecutable");
   if (Dart_IsError(executable_name_name)) {
     return executable_name_name;
   }
   Dart_Handle set_executable_name =
-      Dart_SetField(runtime_options_class,
+      Dart_SetField(platform_type,
                     executable_name_name,
                     dart_executable);
   if (Dart_IsError(set_executable_name)) {
@@ -429,16 +427,25 @@
     return script_name_name;
   }
   Dart_Handle set_script_name =
-      Dart_SetField(runtime_options_class, script_name_name, dart_script);
+      Dart_SetField(platform_type, script_name_name, dart_script);
   if (Dart_IsError(set_script_name)) {
     return set_script_name;
   }
+  Dart_Handle runtime_options_class_name = DartUtils::NewString("_OptionsImpl");
+  if (Dart_IsError(runtime_options_class_name)) {
+    return runtime_options_class_name;
+  }
+  Dart_Handle runtime_options_type = Dart_GetType(
+      io_lib, runtime_options_class_name, 0, NULL);
+  if (Dart_IsError(runtime_options_type)) {
+    return runtime_options_type;
+  }
   Dart_Handle native_name = DartUtils::NewString("_nativeArguments");
   if (Dart_IsError(native_name)) {
     return native_name;
   }
 
-  return Dart_SetField(runtime_options_class, native_name, dart_arguments);
+  return Dart_SetField(runtime_options_type, native_name, dart_arguments);
 }
 
 
diff --git a/runtime/bin/platform.cc b/runtime/bin/platform.cc
index 850be27..495ffe3 100644
--- a/runtime/bin/platform.cc
+++ b/runtime/bin/platform.cc
@@ -79,5 +79,12 @@
   Dart_ExitScope();
 }
 
+
+void FUNCTION_NAME(Platform_GetVersion)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  Dart_SetReturnValue(args, Dart_NewStringFromCString(Dart_VersionString()));
+  Dart_ExitScope();
+}
+
 }  // namespace bin
 }  // namespace dart
diff --git a/runtime/bin/platform_patch.dart b/runtime/bin/platform_patch.dart
index 02ba129..9d21d48 100644
--- a/runtime/bin/platform_patch.dart
+++ b/runtime/bin/platform_patch.dart
@@ -10,4 +10,5 @@
       native "Platform_OperatingSystem";
   /* patch */ static _localHostname() native "Platform_LocalHostname";
   /* patch */ static _environment() native "Platform_Environment";
+  /* patch */ static String _version() native "Platform_GetVersion";
 }
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index ba50c9f..65d271f 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -20,11 +20,13 @@
       List<String> arguments,
       {String workingDirectory,
        Map<String, String> environment,
-       bool runInShell}) {
+       bool includeParentEnvironment: true,
+       bool runInShell: false}) {
     _ProcessImpl process = new _ProcessImpl(executable,
                                             arguments,
                                             workingDirectory,
                                             environment,
+                                            includeParentEnvironment,
                                             runInShell);
     return process._start();
   }
@@ -34,13 +36,15 @@
       List<String> arguments,
       {String workingDirectory,
        Map<String, String> environment,
-       bool runInShell,
+       bool includeParentEnvironment: true,
+       bool runInShell: false,
        Encoding stdoutEncoding: Encoding.SYSTEM,
        Encoding stderrEncoding: Encoding.SYSTEM}) {
     return _runNonInteractiveProcess(executable,
                                      arguments,
                                      workingDirectory,
                                      environment,
+                                     includeParentEnvironment,
                                      runInShell,
                                      stdoutEncoding,
                                      stderrEncoding);
@@ -68,6 +72,7 @@
                List<String> arguments,
                String this._workingDirectory,
                Map<String, String> environment,
+               bool includeParentEnvironment,
                bool runInShell) {
     runInShell = identical(runInShell, true);
     if (runInShell) {
@@ -92,8 +97,7 @@
       }
       _arguments[i] = arguments[i];
       if (Platform.operatingSystem == 'windows') {
-        _arguments[i] = _windowsArgumentEscape(_arguments[i],
-                                               shellEscape: runInShell);
+        _arguments[i] = _windowsArgumentEscape(_arguments[i]);
       }
     }
 
@@ -102,20 +106,23 @@
           "WorkingDirectory is not a String: $_workingDirectory");
     }
 
-    if (environment != null) {
-      var env = environment;
-      if (env is !Map) {
-        throw new ArgumentError("Environment is not a map: $env");
-      }
-      _environment = [];
-      env.forEach((key, value) {
-        if (key is !String || value is !String) {
-          throw new ArgumentError(
-              "Environment key or value is not a string: ($key, $value)");
-        }
-        _environment.add('$key=$value');
-      });
+    _environment = [];
+    if (environment == null) {
+      environment = {};
     }
+    if (environment is !Map) {
+      throw new ArgumentError("Environment is not a map: $environment");
+    }
+    if (identical(true, includeParentEnvironment)) {
+      environment = Platform.environment..addAll(environment);
+    }
+    environment.forEach((key, value) {
+      if (key is !String || value is !String) {
+        throw new ArgumentError(
+            "Environment key or value is not a string: ($key, $value)");
+      }
+      _environment.add('$key=$value');
+    });
 
     // stdin going to process.
     _stdin = new _StdSink(new _Socket._writePipe());
@@ -158,12 +165,11 @@
     return shellArguments;
   }
 
-  String _windowsArgumentEscape(String argument, { bool shellEscape: false }) {
+  String _windowsArgumentEscape(String argument) {
     var result = argument;
     if (argument.contains('\t') ||
         argument.contains(' ') ||
-        // TODO(ajohnsen): Remove shellEscape.
-        (shellEscape && argument.contains('"'))) {
+        argument.contains('"')) {
       // Produce something that the C runtime on Windows will parse
       // back as this string.
 
@@ -333,6 +339,7 @@
                                                 List<String> arguments,
                                                 String workingDirectory,
                                                 Map<String, String> environment,
+                                                bool includeParentEnvironment,
                                                 bool runInShell,
                                                 Encoding stdoutEncoding,
                                                 Encoding stderrEncoding) {
@@ -341,6 +348,7 @@
                        arguments,
                        workingDirectory: workingDirectory,
                        environment: environment,
+                       includeParentEnvironment: includeParentEnvironment,
                        runInShell: runInShell).then((Process p) {
     int pid = p.pid;
 
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc
index 4310aec..e6aacd7 100644
--- a/runtime/bin/secure_socket.cc
+++ b/runtime/bin/secure_socket.cc
@@ -24,6 +24,7 @@
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
 #include "bin/net/nss_memio.h"
+#include "bin/socket.h"
 #include "bin/thread.h"
 #include "bin/utils.h"
 #include "platform/utils.h"
@@ -40,8 +41,47 @@
 // be null if only secure client sockets are used.
 const char* SSLFilter::password_ = NULL;
 
+// Forward declaration.
+static void ProcessFilter(Dart_Port dest_port_id,
+                          Dart_Port reply_port_id,
+                          Dart_CObject* message);
+
+NativeService SSLFilter::filter_service_("FilterService", ProcessFilter, 16);
+
 static const int kSSLFilterNativeFieldIndex = 0;
 
+
+/* Handle an error reported from the NSS library. */
+static void ThrowPRException(const char* exception_type,
+                             const char* message,
+                             bool free_message = false) {
+  PRErrorCode error_code = PR_GetError();
+  const char* error_message = PR_ErrorToString(error_code, PR_LANGUAGE_EN);
+  OSError os_error_struct(error_code, error_message, OSError::kNSS);
+  Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
+  Dart_Handle exception =
+      DartUtils::NewDartIOException(exception_type, message, os_error);
+  if (free_message) {
+    free(const_cast<char*>(message));
+  }
+  Dart_ThrowException(exception);
+}
+
+
+static void ThrowCertificateException(const char* format,
+                                      const char* certificate_name) {
+  int length = strlen(certificate_name);
+  length += strlen(format);
+  char* message = reinterpret_cast<char*>(malloc(length + 1));
+  if (message == NULL) {
+    FATAL("Out of memory formatting CertificateException for throwing");
+  }
+  snprintf(message, length + 1, format, certificate_name);
+  message[length] = '\0';
+  ThrowPRException("CertificateException", message, true);
+}
+
+
 static SSLFilter* GetFilter(Dart_NativeArguments args) {
   SSLFilter* filter;
   Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
@@ -77,21 +117,35 @@
 void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) {
   Dart_EnterScope();
   Dart_Handle host_name_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
-  Dart_Handle port_object = ThrowIfError(Dart_GetNativeArgument(args, 2));
-  bool is_server = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3));
+  Dart_Handle host_sockaddr_storage_object =
+      ThrowIfError(Dart_GetNativeArgument(args, 2));
+  Dart_Handle port_object = ThrowIfError(Dart_GetNativeArgument(args, 3));
+  bool is_server = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4));
   Dart_Handle certificate_name_object =
-      ThrowIfError(Dart_GetNativeArgument(args, 4));
+      ThrowIfError(Dart_GetNativeArgument(args, 5));
   bool request_client_certificate =
-      DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5));
-  bool require_client_certificate =
       DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 6));
-  bool send_client_certificate =
+  bool require_client_certificate =
       DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 7));
+  bool send_client_certificate =
+      DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 8));
 
   const char* host_name = NULL;
   // TODO(whesse): Is truncating a Dart string containing \0 what we want?
   ThrowIfError(Dart_StringToCString(host_name_object, &host_name));
 
+  RawAddr raw_addr;
+  Dart_TypedData_Type type;
+  uint8_t* buffer = NULL;
+  intptr_t len;
+  ThrowIfError(Dart_TypedDataAcquireData(host_sockaddr_storage_object,
+                                         &type,
+                                         reinterpret_cast<void**>(&buffer),
+                                         &len));
+  ASSERT(static_cast<size_t>(len) <= sizeof(raw_addr));
+  memmove(&raw_addr, buffer, len);
+  Dart_TypedDataReleaseData(host_sockaddr_storage_object);
+
   int64_t port;
   if (!DartUtils::GetInt64Value(port_object, &port)) {
     FATAL("The range of port_object was checked in Dart - it cannot fail here");
@@ -106,6 +160,7 @@
   ASSERT(!is_server || certificate_name != NULL);
 
   GetFilter(args)->Connect(host_name,
+                           &raw_addr,
                            static_cast<int>(port),
                            is_server,
                            certificate_name,
@@ -161,22 +216,6 @@
 }
 
 
-void FUNCTION_NAME(SecureSocket_ProcessBuffer)(Dart_NativeArguments args) {
-  Dart_EnterScope();
-  Dart_Handle buffer_id_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
-  int64_t buffer_id = DartUtils::GetIntegerValue(buffer_id_object);
-  if (buffer_id < 0 || buffer_id >= SSLFilter::kNumBuffers) {
-    Dart_ThrowException(DartUtils::NewDartArgumentError(
-        "Illegal argument to ProcessBuffer"));
-  }
-
-  intptr_t bytes_read =
-      GetFilter(args)->ProcessBuffer(static_cast<int>(buffer_id));
-  Dart_SetReturnValue(args, Dart_NewInteger(bytes_read));
-  Dart_ExitScope();
-}
-
-
 void FUNCTION_NAME(SecureSocket_InitializeLibrary)
     (Dart_NativeArguments args) {
   Dart_EnterScope();
@@ -231,13 +270,142 @@
 }
 
 
+void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args));
+  Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer));
+  Dart_ExitScope();
+}
+
+
+/**
+ * Pushes data through the SSL filter, reading and writing from circular
+ * buffers shared with Dart.
+ *
+ * The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to
+ * pass encrypted and plaintext data to and from the C++ SSLFilter object.
+ *
+ * ProcessFilter is called with a CObject array containing the pointer to
+ * the SSLFilter, encoded as an int, and the start and end positions of the
+ * valid data in the four circular buffers.  The function only reads from
+ * the valid data area of the input buffers, and only writes to the free
+ * area of the output buffers.  The function returns the new start and end
+ * positions in the buffers, but it only updates start for input buffers, and
+ * end for output buffers.  Therefore, the Dart thread can simultaneously
+ * write to the free space and end pointer of input buffers, and read from
+ * the data space of output buffers, and modify the start pointer.
+ *
+ * When ProcessFilter returns, the Dart thread is responsible for combining
+ * the updated pointers from Dart and C++, to make the new valid state of
+ * the circular buffer.
+ */
+static void ProcessFilter(Dart_Port dest_port_id,
+                          Dart_Port reply_port_id,
+                          Dart_CObject* message) {
+  CObjectArray args(message);
+  CObjectIntptr filter_object(args[0]);
+  SSLFilter* filter = reinterpret_cast<SSLFilter*>(filter_object.Value());
+  bool in_handshake = CObjectBool(args[1]).Value();
+  int starts[SSLFilter::kNumBuffers];
+  int ends[SSLFilter::kNumBuffers];
+  for (int i = 0; i < SSLFilter::kNumBuffers; ++i) {
+    starts[i] = CObjectInt32(args[2 * i + 2]).Value();
+    ends[i] = CObjectInt32(args[2 * i + 3]).Value();
+  }
+
+  filter->ProcessAllBuffers(starts, ends, in_handshake);
+
+  for (int i = 0; i < SSLFilter::kNumBuffers; ++i) {
+    args[2 * i + 2]->AsApiCObject()->value.as_int32 = starts[i];
+    args[2 * i + 3]->AsApiCObject()->value.as_int32 = ends[i];
+  }
+  Dart_PostCObject(reply_port_id, args.AsApiCObject());
+}
+
+
+void SSLFilter::ProcessAllBuffers(int starts[kNumBuffers],
+                                  int ends[kNumBuffers],
+                                  bool in_handshake) {
+  for (int i = 0; i < kNumBuffers; ++i) {
+    if (in_handshake && (i == kReadPlaintext || i == kWritePlaintext)) continue;
+    int start = starts[i];
+    int end = ends[i];
+    int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_;
+    if (start < 0 || end < 0 || start >= size || end >= size) {
+      FATAL("Out-of-bounds internal buffer access in dart:io SecureSocket");
+    }
+    switch (i) {
+      case kReadPlaintext:
+      case kWriteEncrypted:
+        // Write data to the circular buffer's free space.  If the buffer
+        // is full, neither if statement is executed and nothing happens.
+        if (start <= end) {
+          // If the free space may be split into two segments,
+          // then the first is [end, size), unless start == 0.
+          // Then, since the last free byte is at position start - 2,
+          // the interval is [end, size - 1).
+          int buffer_end = (start == 0) ? size - 1 : size;
+          int bytes = (i == kReadPlaintext) ?
+              ProcessReadPlaintextBuffer(end, buffer_end) :
+              ProcessWriteEncryptedBuffer(end, buffer_end);
+          end += bytes;
+          ASSERT(end <= size);
+          if (end == size) end = 0;
+        }
+        if (start > end + 1) {
+          int bytes =  (i == kReadPlaintext) ?
+              ProcessReadPlaintextBuffer(end, start - 1) :
+              ProcessWriteEncryptedBuffer(end, start - 1);
+          end += bytes;
+          ASSERT(end < start);
+        }
+        ends[i] = end;
+        break;
+      case kReadEncrypted:
+        // Read data from circular buffer.
+        if (end < start) {
+          // Data may be split into two segments.  In this case,
+          // the first is [start, size).
+          int bytes = ProcessReadEncryptedBuffer(start, size);
+          start += bytes;
+          ASSERT(start <= size);
+          if (start == size) start = 0;
+        }
+        if (start < end) {
+          int bytes = ProcessReadEncryptedBuffer(start, end);
+          start += bytes;
+          ASSERT(start <= end);
+        }
+        starts[i] = start;
+        break;
+      case kWritePlaintext:
+        if (end < start) {
+          // Data is split into two segments, [start, size) and [0, end).
+          int bytes = ProcessWritePlaintextBuffer(start, size, 0, end);
+          start += bytes;
+          if (start >= size) start -= size;
+        } else {
+          int bytes = ProcessWritePlaintextBuffer(start, end, 0, 0);
+          start += bytes;
+          ASSERT(start <= end);
+        }
+        starts[i] = start;
+        break;
+      default:
+        UNREACHABLE();
+    }
+  }
+}
+
+
 static Dart_Handle X509FromCertificate(CERTCertificate* certificate) {
   PRTime start_validity;
   PRTime end_validity;
   SECStatus status =
       CERT_GetCertTimes(certificate, &start_validity, &end_validity);
   if (status != SECSuccess) {
-    ThrowPRException("Cannot get validity times from certificate");
+    ThrowPRException("CertificateException",
+                     "Cannot get validity times from certificate");
   }
   int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC;
   int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC;
@@ -248,23 +416,23 @@
   Dart_Handle start_epoch_ms_int = Dart_NewInteger(start_epoch_ms);
   Dart_Handle end_epoch_ms_int = Dart_NewInteger(end_epoch_ms);
 
-  Dart_Handle date_class =
-      DartUtils::GetDartClass(DartUtils::kCoreLibURL, "DateTime");
+  Dart_Handle date_type =
+      DartUtils::GetDartType(DartUtils::kCoreLibURL, "DateTime");
   Dart_Handle from_milliseconds =
       DartUtils::NewString("fromMillisecondsSinceEpoch");
 
   Dart_Handle start_validity_date =
-      Dart_New(date_class, from_milliseconds, 1, &start_epoch_ms_int);
+      Dart_New(date_type, from_milliseconds, 1, &start_epoch_ms_int);
   Dart_Handle end_validity_date =
-      Dart_New(date_class, from_milliseconds, 1, &end_epoch_ms_int);
+      Dart_New(date_type, from_milliseconds, 1, &end_epoch_ms_int);
 
-  Dart_Handle x509_class =
-      DartUtils::GetDartClass(DartUtils::kIOLibURL, "X509Certificate");
+  Dart_Handle x509_type =
+      DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate");
   Dart_Handle arguments[] = { subject_name_object,
                               issuer_name_object,
                               start_validity_date,
                               end_validity_date };
-  return Dart_New(x509_class, Dart_Null(), 4, arguments);
+  return Dart_New(x509_type, Dart_Null(), 4, arguments);
 }
 
 
@@ -291,25 +459,21 @@
   // Create SSLFilter buffers as ExternalUint8Array objects.
   Dart_Handle dart_buffers_object = ThrowIfError(
       Dart_GetField(dart_this, DartUtils::NewString("buffers")));
-  Dart_Handle dart_buffer_object =
-      Dart_ListGetAt(dart_buffers_object, kReadPlaintext);
-  Dart_Handle external_buffer_class =
-      Dart_InstanceGetClass(dart_buffer_object);
+  Dart_Handle secure_filter_impl_type =
+      Dart_InstanceGetType(dart_this);
   Dart_Handle dart_buffer_size = ThrowIfError(
-      Dart_GetField(external_buffer_class, DartUtils::NewString("SIZE")));
+      Dart_GetField(secure_filter_impl_type, DartUtils::NewString("SIZE")));
   int64_t buffer_size = DartUtils::GetIntegerValue(dart_buffer_size);
   Dart_Handle dart_encrypted_buffer_size = ThrowIfError(
-      Dart_GetField(external_buffer_class,
+      Dart_GetField(secure_filter_impl_type,
                     DartUtils::NewString("ENCRYPTED_SIZE")));
   int64_t encrypted_buffer_size =
       DartUtils::GetIntegerValue(dart_encrypted_buffer_size);
-  if (buffer_size <= 0 || buffer_size > 1024 * 1024) {
-    Dart_ThrowException(
-        DartUtils::NewString("Invalid buffer size in _ExternalBuffer"));
+  if (buffer_size <= 0 || buffer_size > 1 * MB) {
+    FATAL("Invalid buffer size in _ExternalBuffer");
   }
-  if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1024 * 1024) {
-    Dart_ThrowException(DartUtils::NewString(
-        "Invalid encrypted buffer size in _ExternalBuffer"));
+  if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1 * MB) {
+    FATAL("Invalid encrypted buffer size in _ExternalBuffer");
   }
   buffer_size_ = static_cast<int>(buffer_size);
   encrypted_buffer_size_ = static_cast<int>(encrypted_buffer_size);
@@ -317,7 +481,7 @@
 
   Dart_Handle data_identifier = DartUtils::NewString("data");
   for (int i = 0; i < kNumBuffers; ++i) {
-    int size = isEncrypted(i) ? encrypted_buffer_size_ : buffer_size_;
+    int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_;
     dart_buffer_objects_[i] =
         Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i));
     ASSERT(dart_buffer_objects_[i] != NULL);
@@ -373,14 +537,16 @@
       status = NSS_NoDB_Init(NULL);
       if (status != SECSuccess) {
         mutex_.Unlock();  // MutexLocker destructor not called when throwing.
-        ThrowPRException("Failed NSS_NoDB_Init call.");
+        ThrowPRException("TlsException",
+                         "Failed NSS_NoDB_Init call.");
       }
       if (use_builtin_root_certificates) {
         SECMODModule* module = SECMOD_LoadUserModule(
             const_cast<char*>(builtin_roots_module), NULL, PR_FALSE);
         if (!module) {
           mutex_.Unlock();  // MutexLocker destructor not called when throwing.
-          ThrowPRException("Failed to load builtin root certificates.");
+          ThrowPRException("TlsException",
+                           "Failed to load builtin root certificates.");
         }
       }
     } else {
@@ -395,7 +561,8 @@
                               init_flags);
       if (status != SECSuccess) {
         mutex_.Unlock();  // MutexLocker destructor not called when throwing.
-        ThrowPRException("Failed NSS_Init call.");
+        ThrowPRException("TlsException",
+                         "Failed NSS_Init call.");
       }
     }
     library_initialized_ = true;
@@ -403,23 +570,29 @@
     status = NSS_SetDomesticPolicy();
     if (status != SECSuccess) {
       mutex_.Unlock();  // MutexLocker destructor not called when throwing.
-      ThrowPRException("Failed NSS_SetDomesticPolicy call.");
+      ThrowPRException("TlsException",
+                       "Failed NSS_SetDomesticPolicy call.");
     }
     // Enable TLS, as well as SSL3 and SSL2.
     status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE);
     if (status != SECSuccess) {
       mutex_.Unlock();  // MutexLocker destructor not called when throwing.
-      ThrowPRException("Failed SSL_OptionSetDefault enable TLS call.");
+      ThrowPRException("TlsException",
+                       "Failed SSL_OptionSetDefault enable TLS call.");
     }
     status = SSL_ConfigServerSessionIDCache(0, 0, 0, NULL);
     if (status != SECSuccess) {
       mutex_.Unlock();  // MutexLocker destructor not called when throwing.
-      ThrowPRException("Failed SSL_ConfigServerSessionIDCache call.");
+      ThrowPRException("TlsException",
+                       "Failed SSL_ConfigServerSessionIDCache call.");
     }
 
   } else if (report_duplicate_initialization) {
     mutex_.Unlock();  // MutexLocker destructor not called when throwing.
-    ThrowException("Called SSLFilter::InitializeLibrary more than once");
+    // Like ThrowPRException, without adding an OSError.
+    Dart_ThrowException(DartUtils::NewDartIOException("TlsException",
+        "Called SecureSocket.initialize more than once",
+        Dart_Null()));
   }
 }
 
@@ -457,6 +630,7 @@
 
 
 void SSLFilter::Connect(const char* host_name,
+                        RawAddr* raw_addr,
                         int port,
                         bool is_server,
                         const char* certificate_name,
@@ -465,7 +639,7 @@
                         bool send_client_certificate) {
   is_server_ = is_server;
   if (in_handshake_) {
-    ThrowException("Connect called while already in handshake state.");
+    FATAL("Connect called twice on the same _SecureFilter.");
   }
 
   if (!is_server && certificate_name != NULL) {
@@ -474,9 +648,14 @@
 
   filter_ = SSL_ImportFD(NULL, filter_);
   if (filter_ == NULL) {
-    ThrowPRException("Failed SSL_ImportFD call");
+    ThrowPRException("TlsException", "Failed SSL_ImportFD call");
   }
 
+  SSLVersionRange vrange;
+  vrange.min = SSL_LIBRARY_VERSION_3_0;
+  vrange.max = SSL_LIBRARY_VERSION_TLS_1_1;
+  SSL_VersionRangeSet(filter_, &vrange);
+
   SECStatus status;
   if (is_server) {
     PK11_SetPasswordFunc(PasswordCallback);
@@ -486,13 +665,15 @@
       // Look up certificate using the distinguished name (DN) certificate_name.
       CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB();
       if (certificate_database == NULL) {
-        ThrowPRException("Certificate database cannot be loaded");
+        ThrowPRException("CertificateException",
+                         "Certificate database cannot be loaded");
       }
       certificate = CERT_FindCertByNameString(certificate_database,
           const_cast<char*>(certificate_name));
       if (certificate == NULL) {
-        ThrowPRException(
-            "Cannot find server certificate by distinguished name");
+        ThrowCertificateException(
+            "Cannot find server certificate by distinguished name: %s",
+            certificate_name);
       }
     } else {
       // Look up certificate using the nickname certificate_name.
@@ -500,7 +681,9 @@
           const_cast<char*>(certificate_name),
           static_cast<void*>(const_cast<char*>(password_)));
       if (certificate == NULL) {
-        ThrowPRException("Cannot find server certificate by nickname");
+        ThrowCertificateException(
+            "Cannot find server certificate by nickname: %s",
+            certificate_name);
       }
     }
     SECKEYPrivateKey* key = PK11_FindKeyByAnyCert(
@@ -509,10 +692,12 @@
     if (key == NULL) {
       CERT_DestroyCertificate(certificate);
       if (PR_GetError() == -8177) {
-        ThrowPRException("Certificate database password incorrect");
+        ThrowPRException("CertificateException",
+                         "Certificate database password incorrect");
       } else {
-        ThrowPRException("Failed PK11_FindKeyByAnyCert call."
-                         " Cannot find private key for certificate");
+        ThrowCertificateException(
+            "Cannot find private key for certificate %s",
+            certificate_name);
       }
     }
     // kt_rsa (key type RSA) is an enum constant from the NSS libraries.
@@ -521,23 +706,28 @@
     CERT_DestroyCertificate(certificate);
     SECKEY_DestroyPrivateKey(key);
     if (status != SECSuccess) {
-      ThrowPRException("Failed SSL_ConfigSecureServer call");
+      ThrowCertificateException(
+          "Failed SSL_ConfigSecureServer call with certificate %s",
+          certificate_name);
     }
 
     if (request_client_certificate) {
       status = SSL_OptionSet(filter_, SSL_REQUEST_CERTIFICATE, PR_TRUE);
       if (status != SECSuccess) {
-        ThrowPRException("Failed SSL_OptionSet(REQUEST_CERTIFICATE) call");
+        ThrowPRException("TlsException",
+                         "Failed SSL_OptionSet(REQUEST_CERTIFICATE) call");
       }
       PRBool require_cert = require_client_certificate ? PR_TRUE : PR_FALSE;
       status = SSL_OptionSet(filter_, SSL_REQUIRE_CERTIFICATE, require_cert);
       if (status != SECSuccess) {
-        ThrowPRException("Failed SSL_OptionSet(REQUIRE_CERTIFICATE) call");
+        ThrowPRException("TlsException",
+                         "Failed SSL_OptionSet(REQUIRE_CERTIFICATE) call");
       }
     }
   } else {  // Client.
     if (SSL_SetURL(filter_, host_name) == -1) {
-      ThrowPRException("Failed SetURL call");
+      ThrowPRException("TlsException",
+                       "Failed SetURL call");
     }
 
     // This disables the SSL session cache for client connections.
@@ -545,7 +735,8 @@
     // TODO(7230): Reenable session cache, without breaking client connections.
     status = SSL_OptionSet(filter_, SSL_NO_CACHE, PR_TRUE);
     if (status != SECSuccess) {
-      ThrowPRException("Failed SSL_OptionSet(NO_CACHE) call");
+      ThrowPRException("TlsException",
+                       "Failed SSL_OptionSet(NO_CACHE) call");
     }
 
     if (send_client_certificate) {
@@ -554,7 +745,8 @@
           NSS_GetClientAuthData,
           static_cast<void*>(client_certificate_name_));
       if (status != SECSuccess) {
-        ThrowPRException("Failed SSL_GetClientAuthDataHook call");
+        ThrowPRException("TlsException",
+                         "Failed SSL_GetClientAuthDataHook call");
       }
     }
   }
@@ -567,22 +759,28 @@
   PRBool as_server = is_server ? PR_TRUE : PR_FALSE;
   status = SSL_ResetHandshake(filter_, as_server);
   if (status != SECSuccess) {
-    ThrowPRException("Failed SSL_ResetHandshake call");
+    ThrowPRException("TlsException",
+                     "Failed SSL_ResetHandshake call");
   }
 
-  // SetPeerAddress
-  PRNetAddr host_address;
-  PRAddrInfo* info = PR_GetAddrInfoByName(host_name,
-                                          PR_AF_UNSPEC,
-                                          PR_AI_ADDRCONFIG);
-  if (info == NULL) {
-    ThrowPRException("Failed PR_GetAddrInfoByName call");
-  }
+  // Set the peer address from the address passed. The DNS has already
+  // been done in Dart code, so just use that address. This relies on
+  // following about PRNetAddr: "The raw member of the union is
+  // equivalent to struct sockaddr", which is stated in the NSS
+  // documentation.
+  PRNetAddr peername;
+  memset(&peername, 0, sizeof(peername));
+  intptr_t len = SocketAddress::GetAddrLength(raw_addr);
+  ASSERT(static_cast<size_t>(len) <= sizeof(peername));
+  memmove(&peername, &raw_addr->addr, len);
 
-  PR_EnumerateAddrInfo(0, info, port, &host_address);
+  // Adjust the address family field for BSD, whose sockaddr
+  // structure has a one-byte length and one-byte address family
+  // field at the beginning.  PRNetAddr has a two-byte address
+  // family field at the beginning.
+  peername.raw.family = raw_addr->addr.sa_family;
 
-  memio_SetPeerName(filter_, &host_address);
-  PR_FreeAddrInfo(info);
+  memio_SetPeerName(filter_, &peername);
 }
 
 
@@ -602,9 +800,11 @@
       }
     } else {
       if (is_server_) {
-        ThrowPRException("Unexpected handshake error in server");
+        ThrowPRException("HandshakeException",
+                         "Handshake error in server");
       } else {
-        ThrowPRException("Unexpected handshake error in client");
+        ThrowPRException("HandshakeException",
+                         "Handshake error in client");
       }
     }
   }
@@ -626,106 +826,112 @@
 }
 
 
-intptr_t SSLFilter::ProcessBuffer(int buffer_index) {
-  int size = isEncrypted(buffer_index) ? encrypted_buffer_size_ : buffer_size_;
-  Dart_Handle buffer_object =
-      Dart_HandleFromPersistent(dart_buffer_objects_[buffer_index]);
-  Dart_Handle start_object = ThrowIfError(
-      Dart_GetField(buffer_object, Dart_HandleFromPersistent(string_start_)));
-  Dart_Handle length_object = ThrowIfError(
-      Dart_GetField(buffer_object, Dart_HandleFromPersistent(string_length_)));
-  int64_t unsafe_start = DartUtils::GetIntegerValue(start_object);
-  int64_t unsafe_length = DartUtils::GetIntegerValue(length_object);
-  ASSERT(unsafe_start >= 0);
-  ASSERT(unsafe_start < size);
-  ASSERT(unsafe_length >= 0);
-  ASSERT(unsafe_length <= size);
-  int start = static_cast<int>(unsafe_start);
-  int length = static_cast<int>(unsafe_length);
-  uint8_t* buffer = buffers_[buffer_index];
-
+intptr_t SSLFilter::ProcessReadPlaintextBuffer(int start, int end) {
+  int length = end - start;
   int bytes_processed = 0;
-  switch (buffer_index) {
-    case kReadPlaintext: {
-      int bytes_free = size - start - length;
-      bytes_processed = PR_Read(filter_,
-                                buffer + start + length,
-                                bytes_free);
-      if (bytes_processed < 0) {
-        ASSERT(bytes_processed == -1);
-        // TODO(whesse): Handle unexpected errors here.
-        PRErrorCode pr_error = PR_GetError();
-        if (PR_WOULD_BLOCK_ERROR != pr_error) {
-          ThrowPRException("Error reading plaintext from SSLFilter");
-        }
-        bytes_processed = 0;
+  if (length > 0) {
+    bytes_processed = PR_Read(filter_,
+                              buffers_[kReadPlaintext] + start,
+                              length);
+    if (bytes_processed < 0) {
+      ASSERT(bytes_processed == -1);
+      PRErrorCode pr_error = PR_GetError();
+      if (PR_WOULD_BLOCK_ERROR != pr_error) {
+        // TODO(11383): Handle unexpected errors here.
+        FATAL("Error reading plaintext from SSLFilter");
       }
-      break;
-    }
-
-    case kWriteEncrypted: {
-      const uint8_t* buf1;
-      const uint8_t* buf2;
-      unsigned int len1;
-      unsigned int len2;
-      int bytes_free = size - start - length;
-      memio_Private* secret = memio_GetSecret(filter_);
-      memio_GetWriteParams(secret, &buf1, &len1, &buf2, &len2);
-      int bytes_to_send =
-          dart::Utils::Minimum(len1, static_cast<unsigned>(bytes_free));
-      if (bytes_to_send > 0) {
-        memmove(buffer + start + length, buf1, bytes_to_send);
-        bytes_processed = bytes_to_send;
-      }
-      bytes_to_send = dart::Utils::Minimum(len2,
-          static_cast<unsigned>(bytes_free - bytes_processed));
-      if (bytes_to_send > 0) {
-        memmove(buffer + start + length + bytes_processed, buf2,
-                bytes_to_send);
-        bytes_processed += bytes_to_send;
-      }
-      if (bytes_processed > 0) {
-        memio_PutWriteResult(secret, bytes_processed);
-      }
-      break;
-    }
-
-    case kReadEncrypted: {
-      if (length > 0) {
-        bytes_processed = length;
-        memio_Private* secret = memio_GetSecret(filter_);
-        uint8_t* filter_buf;
-        int free_bytes = memio_GetReadParams(secret, &filter_buf);
-        if (free_bytes < bytes_processed) bytes_processed = free_bytes;
-        memmove(filter_buf,
-                buffer + start,
-                bytes_processed);
-        memio_PutReadResult(secret, bytes_processed);
-      }
-      break;
-    }
-
-    case kWritePlaintext: {
-      if (length > 0) {
-        bytes_processed = PR_Write(filter_,
-                                   buffer + start,
-                                   length);
-      }
-
-      if (bytes_processed < 0) {
-        ASSERT(bytes_processed == -1);
-        // TODO(whesse): Handle unexpected errors here.
-        PRErrorCode pr_error = PR_GetError();
-        if (PR_WOULD_BLOCK_ERROR != pr_error) {
-          ThrowPRException("Error reading plaintext from SSLFilter");
-        }
-        bytes_processed = 0;
-      }
-      break;
+      bytes_processed = 0;
     }
   }
   return bytes_processed;
 }
 
+
+intptr_t SSLFilter::ProcessWritePlaintextBuffer(int start1, int end1,
+                                                int start2, int end2) {
+  PRIOVec ranges[2];
+  uint8_t* buffer = buffers_[kWritePlaintext];
+  ranges[0].iov_base = reinterpret_cast<char*>(buffer + start1);
+  ranges[0].iov_len = end1 - start1;
+  ranges[1].iov_base = reinterpret_cast<char*>(buffer + start2);
+  ranges[1].iov_len = end2 - start2;
+  int bytes_processed = PR_Writev(filter_, ranges, 2, PR_INTERVAL_NO_TIMEOUT);
+  if (bytes_processed < 0) {
+    ASSERT(bytes_processed == -1);
+    PRErrorCode pr_error = PR_GetError();
+    if (PR_WOULD_BLOCK_ERROR != pr_error) {
+      // TODO(11383): Handle unexpected errors here.
+      FATAL("Error reading plaintext from SSLFilter");
+    }
+    bytes_processed = 0;
+  }
+  return bytes_processed;
+}
+
+
+intptr_t SSLFilter::ProcessReadEncryptedBuffer(int start, int end) {
+  int length = end - start;
+  int bytes_processed = 0;
+  if (length > 0) {
+    memio_Private* secret = memio_GetSecret(filter_);
+    uint8_t* filter_buf;
+    int free_bytes = memio_GetReadParams(secret, &filter_buf);
+    bytes_processed = dart::Utils::Minimum(length, free_bytes);
+    memmove(filter_buf, buffers_[kReadEncrypted] + start, bytes_processed);
+    memio_PutReadResult(secret, bytes_processed);
+  }
+  return bytes_processed;
+}
+
+
+intptr_t SSLFilter::ProcessWriteEncryptedBuffer(int start, int end) {
+  int length = end - start;
+  int bytes_processed = 0;
+  if (length > 0) {
+    uint8_t* buffer = buffers_[kWriteEncrypted];
+    const uint8_t* buf1;
+    const uint8_t* buf2;
+    unsigned int len1;
+    unsigned int len2;
+    memio_Private* secret = memio_GetSecret(filter_);
+    memio_GetWriteParams(secret, &buf1, &len1, &buf2, &len2);
+    int bytes_to_send =
+        dart::Utils::Minimum(len1, static_cast<unsigned>(length));
+    if (bytes_to_send > 0) {
+      memmove(buffer + start, buf1, bytes_to_send);
+      bytes_processed = bytes_to_send;
+    }
+    bytes_to_send = dart::Utils::Minimum(len2,
+        static_cast<unsigned>(length - bytes_processed));
+    if (bytes_to_send > 0) {
+      memmove(buffer + start + bytes_processed, buf2, bytes_to_send);
+      bytes_processed += bytes_to_send;
+    }
+    if (bytes_processed > 0) {
+      memio_PutWriteResult(secret, bytes_processed);
+    }
+  }
+  return bytes_processed;
+}
+
+
+Dart_Port SSLFilter::GetServicePort() {
+  return filter_service_.GetServicePort();
+}
+
+
+void FUNCTION_NAME(SecureSocket_NewServicePort)(Dart_NativeArguments args) {
+  Dart_EnterScope();
+  Dart_SetReturnValue(args, Dart_Null());
+  Dart_Port service_port = SSLFilter::GetServicePort();
+  if (service_port != ILLEGAL_PORT) {
+    // Return a send port for the service port.
+    Dart_Handle send_port = Dart_NewSendPort(service_port);
+    Dart_SetReturnValue(args, send_port);
+  }
+  Dart_ExitScope();
+}
+
+
 }  // namespace bin
 }  // namespace dart
diff --git a/runtime/bin/secure_socket.h b/runtime/bin/secure_socket.h
index 010b5ad..2f8225e 100644
--- a/runtime/bin/secure_socket.h
+++ b/runtime/bin/secure_socket.h
@@ -20,29 +20,13 @@
 
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
+#include "bin/socket.h"
 #include "bin/utils.h"
+#include "bin/native_service.h"
 
 namespace dart {
 namespace bin {
 
-static void ThrowException(const char* message) {
-  Dart_Handle socket_exception =
-      DartUtils::NewDartSocketException(message, Dart_Null());
-  Dart_ThrowException(socket_exception);
-}
-
-
-/* Handle an error reported from the NSS library. */
-static void ThrowPRException(const char* message) {
-  PRErrorCode error_code = PR_GetError();
-  const char* error_message = PR_ErrorToString(error_code, PR_LANGUAGE_EN);
-  OSError os_error_struct(error_code, error_message, OSError::kNSS);
-  Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
-  Dart_Handle socket_exception =
-      DartUtils::NewDartSocketException(message, os_error);
-  Dart_ThrowException(socket_exception);
-}
-
 /*
  * SSLFilter encapsulates the NSS SSL(TLS) code in a filter, that communicates
  * with the containing _SecureFilterImpl Dart object through four shared
@@ -73,6 +57,7 @@
 
   void Init(Dart_Handle dart_this);
   void Connect(const char* host,
+               RawAddr* raw_addr,
                int port,
                bool is_server,
                const char* certificate_name,
@@ -86,18 +71,27 @@
   Dart_Handle bad_certificate_callback() {
     return Dart_HandleFromPersistent(bad_certificate_callback_);
   }
+  intptr_t ProcessReadPlaintextBuffer(int start, int end);
+  intptr_t ProcessWritePlaintextBuffer(int start1, int end1,
+                                       int start2, int end2);
+  intptr_t ProcessReadEncryptedBuffer(int start, int end);
+  intptr_t ProcessWriteEncryptedBuffer(int start, int end);
+  void ProcessAllBuffers(int starts[kNumBuffers],
+                         int ends[kNumBuffers],
+                         bool in_handshake);
+  Dart_Handle PeerCertificate();
   static void InitializeLibrary(const char* certificate_database,
                                 const char* password,
                                 bool use_builtin_root_certificates,
                                 bool report_duplicate_initialization = true);
-  intptr_t ProcessBuffer(int bufferIndex);
-  Dart_Handle PeerCertificate();
+  static Dart_Port GetServicePort();
 
  private:
   static const int kMemioBufferSize = 20 * KB;
   static bool library_initialized_;
   static const char* password_;
   static dart::Mutex mutex_;  // To protect library initialization.
+  static NativeService filter_service_;
 
   uint8_t* buffers_[kNumBuffers];
   int buffer_size_;
@@ -112,7 +106,7 @@
   char* client_certificate_name_;
   PRFileDesc* filter_;
 
-  static bool isEncrypted(int i) {
+  static bool isBufferEncrypted(int i) {
     return static_cast<BufferIndex>(i) >= kFirstEncrypted;
   }
   void InitializeBuffers(Dart_Handle dart_this);
diff --git a/runtime/bin/secure_socket_patch.dart b/runtime/bin/secure_socket_patch.dart
index fdff0d5..4b7c5ab 100644
--- a/runtime/bin/secure_socket_patch.dart
+++ b/runtime/bin/secure_socket_patch.dart
@@ -15,6 +15,9 @@
 
 patch class _SecureFilter {
   /* patch */ factory _SecureFilter() => new _SecureFilterImpl();
+
+  /* patch */ static SendPort _newServicePort()
+      native "SecureSocket_NewServicePort";
 }
 
 
@@ -49,14 +52,22 @@
 class _SecureFilterImpl
     extends NativeFieldWrapperClass1
     implements _SecureFilter {
+  // Performance is improved if a full buffer of plaintext fits
+  // in the encrypted buffer, when encrypted.
+  static final int SIZE = 8 * 1024;
+  static final int ENCRYPTED_SIZE = 10 * 1024;
+
   _SecureFilterImpl() {
     buffers = new List<_ExternalBuffer>(_RawSecureSocket.NUM_BUFFERS);
     for (int i = 0; i < _RawSecureSocket.NUM_BUFFERS; ++i) {
-      buffers[i] = new _ExternalBuffer();
+      buffers[i] = new _ExternalBuffer(_RawSecureSocket._isBufferEncrypted(i) ?
+                                       ENCRYPTED_SIZE :
+                                       SIZE);
     }
   }
 
   void connect(String hostName,
+               Uint8List sockaddrStorage,
                int port,
                bool is_server,
                String certificateName,
@@ -77,13 +88,14 @@
 
   X509Certificate get peerCertificate native "SecureSocket_PeerCertificate";
 
-  int processBuffer(int bufferIndex) native "SecureSocket_ProcessBuffer";
-
   void registerBadCertificateCallback(Function callback)
       native "SecureSocket_RegisterBadCertificateCallback";
 
   void registerHandshakeCompleteCallback(Function handshakeCompleteHandler)
       native "SecureSocket_RegisterHandshakeCompleteCallback";
 
+  // This is a security issue, as it exposes a raw pointer to Dart code.
+  int _pointer() native "SecureSocket_FilterPointer";
+
   List<_ExternalBuffer> buffers;
 }
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 89e6b00..41bcc9e 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -74,7 +74,7 @@
       if (Dart_IsError(error)) Dart_PropagateError(error);
       Dart_ThrowException(error);
   }
-  int len = SocketAddress::GetAddrLength(raw);
+  int len = SocketAddress::GetAddrLength(&raw);
   Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len);
   if (Dart_IsError(result)) Dart_PropagateError(result);
   Dart_ListSetAsBytes(result, 0, reinterpret_cast<uint8_t *>(&raw), len);
@@ -130,6 +130,7 @@
 
 void FUNCTION_NAME(Socket_Read)(Dart_NativeArguments args) {
   Dart_EnterScope();
+  static bool short_socket_reads = Dart_IsVMFlagSet("short_socket_read");
   Dart_Handle socket_obj = Dart_GetNativeArgument(args, 0);
   intptr_t socket = 0;
   Dart_Handle err = Socket::GetSocketIdNativeField(socket_obj, &socket);
@@ -142,6 +143,9 @@
       if (length == -1 || available < length) {
         length = available;
       }
+      if (short_socket_reads) {
+        length = (length + 1) / 2;
+      }
       uint8_t* buffer = NULL;
       Dart_Handle result = IOBuffer::Allocate(length, &buffer);
       if (Dart_IsError(result)) Dart_PropagateError(result);
@@ -149,12 +153,19 @@
       intptr_t bytes_read = Socket::Read(socket, buffer, length);
       if (bytes_read == length) {
         Dart_SetReturnValue(args, result);
-      } else if (bytes_read == 0) {
-        // On MacOS when reading from a tty Ctrl-D will result in one
-        // byte reported as available. Attempting to read it out will
-        // result in zero bytes read. When that happens there is no
-        // data which is indicated by a null return value.
-        Dart_SetReturnValue(args, Dart_Null());
+      } else if (bytes_read < length) {
+        // On MacOS when reading from a tty Ctrl-D will result in reading one
+        // less byte then reported as available.
+        if (bytes_read == 0) {
+          Dart_SetReturnValue(args, Dart_Null());
+        } else {
+          uint8_t* new_buffer = NULL;
+          Dart_Handle new_result = IOBuffer::Allocate(bytes_read, &new_buffer);
+          if (Dart_IsError(new_result)) Dart_PropagateError(new_result);
+          ASSERT(new_buffer != NULL);
+          memmove(new_buffer, buffer, bytes_read);
+          Dart_SetReturnValue(args, new_result);
+        }
       } else {
         ASSERT(bytes_read == -1);
         Dart_SetReturnValue(args, DartUtils::NewDartOSError());
@@ -175,57 +186,6 @@
 }
 
 
-void FUNCTION_NAME(Socket_ReadList)(Dart_NativeArguments args) {
-  Dart_EnterScope();
-  static bool short_socket_reads = Dart_IsVMFlagSet("short_socket_read");
-  Dart_Handle socket_obj = Dart_GetNativeArgument(args, 0);
-  intptr_t socket = 0;
-  Dart_Handle err = Socket::GetSocketIdNativeField(socket_obj, &socket);
-  if (Dart_IsError(err)) Dart_PropagateError(err);
-  Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
-  int64_t offset = 0;
-  int64_t length = 0;
-  Dart_Handle offset_obj = Dart_GetNativeArgument(args, 2);
-  Dart_Handle length_obj = Dart_GetNativeArgument(args, 3);
-  if (Dart_IsList(buffer_obj) &&
-      DartUtils::GetInt64Value(offset_obj, &offset) &&
-      DartUtils::GetInt64Value(length_obj, &length)) {
-    intptr_t buffer_len = 0;
-    Dart_Handle result = Dart_ListLength(buffer_obj, &buffer_len);
-    if (Dart_IsError(result)) {
-      Dart_PropagateError(result);
-    }
-    ASSERT((offset + length) <= buffer_len);
-    if (short_socket_reads) {
-      length = (length + 1) / 2;
-    }
-    uint8_t* buffer = new uint8_t[length];
-    intptr_t bytes_read = Socket::Read(socket, buffer, length);
-    if (bytes_read > 0) {
-      Dart_Handle result =
-          Dart_ListSetAsBytes(buffer_obj, offset, buffer, bytes_read);
-      if (Dart_IsError(result)) {
-        delete[] buffer;
-        Dart_PropagateError(result);
-      }
-    }
-    delete[] buffer;
-    if (bytes_read >= 0) {
-      Dart_SetReturnValue(args, Dart_NewInteger(bytes_read));
-    } else {
-      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
-    }
-  } else {
-    OSError os_error(-1, "Invalid argument", OSError::kUnknown);
-    Dart_Handle err = DartUtils::NewDartOSError(&os_error);
-    if (Dart_IsError(err)) Dart_PropagateError(err);
-    Dart_SetReturnValue(args, err);
-  }
-
-  Dart_ExitScope();
-}
-
-
 void FUNCTION_NAME(Socket_WriteList)(Dart_NativeArguments args) {
   Dart_EnterScope();
   static bool short_socket_writes = Dart_IsVMFlagSet("short_socket_write");
@@ -446,7 +406,7 @@
     CObjectInt32 type(request[2]);
     CObject* result = NULL;
     OSError* os_error = NULL;
-    SocketAddresses* addresses =
+    AddressList<SocketAddress>* addresses =
         Socket::LookupAddress(host.CString(), type.Value(), &os_error);
     if (addresses != NULL) {
       CObjectArray* array = new CObjectArray(
@@ -466,10 +426,10 @@
 
         RawAddr raw = addr->addr();
         CObjectUint8Array* data = new CObjectUint8Array(CObject::NewUint8Array(
-            SocketAddress::GetAddrLength(raw)));
+            SocketAddress::GetAddrLength(&raw)));
         memmove(data->Buffer(),
                 reinterpret_cast<void *>(&raw),
-                SocketAddress::GetAddrLength(raw));
+                SocketAddress::GetAddrLength(&raw));
 
         entry->SetAt(2, data);
         array->SetAt(i + 1, entry);
@@ -486,6 +446,81 @@
 }
 
 
+static CObject* ReverseLookupRequest(const CObjectArray& request) {
+  if (request.Length() == 2 &&
+      request[1]->IsTypedData()) {
+    CObjectUint8Array addr_object(request[1]);
+    RawAddr addr;
+    memmove(reinterpret_cast<void *>(&addr),
+            addr_object.Buffer(),
+            addr_object.Length());
+    OSError* os_error = NULL;
+    const intptr_t kMaxHostLength = 1025;
+    char host[kMaxHostLength];
+    if (Socket::ReverseLookup(addr, host, kMaxHostLength, &os_error)) {
+      return new CObjectString(CObject::NewString(host));
+    } else {
+      CObject* result = CObject::NewOSError(os_error);
+      delete os_error;
+      return result;
+    }
+  }
+  return CObject::IllegalArgumentError();
+}
+
+
+
+static CObject* ListInterfacesRequest(const CObjectArray& request) {
+  if (request.Length() == 2 &&
+      request[1]->IsInt32()) {
+    CObjectInt32 type(request[1]);
+    CObject* result = NULL;
+    OSError* os_error = NULL;
+    AddressList<InterfaceSocketAddress>* addresses = Socket::ListInterfaces(
+        type.Value(), &os_error);
+    if (addresses != NULL) {
+      CObjectArray* array = new CObjectArray(
+          CObject::NewArray(addresses->count() + 1));
+      array->SetAt(0, new CObjectInt32(CObject::NewInt32(0)));
+      for (intptr_t i = 0; i < addresses->count(); i++) {
+        InterfaceSocketAddress* interface = addresses->GetAt(i);
+        SocketAddress* addr = interface->socket_address();
+        CObjectArray* entry = new CObjectArray(CObject::NewArray(4));
+
+        CObjectInt32* type = new CObjectInt32(
+            CObject::NewInt32(addr->GetType()));
+        entry->SetAt(0, type);
+
+        CObjectString* as_string = new CObjectString(CObject::NewString(
+            addr->as_string()));
+        entry->SetAt(1, as_string);
+
+        RawAddr raw = addr->addr();
+        CObjectUint8Array* data = new CObjectUint8Array(CObject::NewUint8Array(
+            SocketAddress::GetAddrLength(&raw)));
+        memmove(data->Buffer(),
+                reinterpret_cast<void *>(&raw),
+                SocketAddress::GetAddrLength(&raw));
+        entry->SetAt(2, data);
+
+        CObjectString* interface_name = new CObjectString(CObject::NewString(
+            interface->interface_name()));
+        entry->SetAt(3, interface_name);
+
+        array->SetAt(i + 1, entry);
+      }
+      result = array;
+      delete addresses;
+    } else {
+      result = CObject::NewOSError(os_error);
+      delete os_error;
+    }
+    return result;
+  }
+  return CObject::IllegalArgumentError();
+}
+
+
 void SocketService(Dart_Port dest_port_id,
                    Dart_Port reply_port_id,
                    Dart_CObject* message) {
@@ -498,6 +533,12 @@
         case Socket::kLookupRequest:
           response = LookupRequest(request);
           break;
+        case Socket::kListInterfacesRequest:
+          response = ListInterfacesRequest(request);
+          break;
+        case Socket::kReverseLookupRequest:
+          response = ReverseLookupRequest(request);
+          break;
         default:
           UNREACHABLE();
       }
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index 46780fc..ffca207 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -51,7 +51,9 @@
     ADDRESS_LAST = ADDRESS_ANY_IP_V6,
   };
 
-  explicit SocketAddress(struct addrinfo* addrinfo);
+  explicit SocketAddress(struct sockaddr* sockaddr);
+
+  ~SocketAddress() {}
 
   int GetType() {
     if (addr_.ss.ss_family == AF_INET6) return TYPE_IPV6;
@@ -61,8 +63,8 @@
   const char* as_string() const { return as_string_; }
   const RawAddr& addr() const { return addr_; }
 
-  static intptr_t GetAddrLength(const RawAddr& addr) {
-    return addr.ss.ss_family == AF_INET6 ?
+  static intptr_t GetAddrLength(const RawAddr* addr) {
+    return addr->ss.ss_family == AF_INET6 ?
         sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
   }
 
@@ -96,13 +98,36 @@
   DISALLOW_COPY_AND_ASSIGN(SocketAddress);
 };
 
-class SocketAddresses {
+class InterfaceSocketAddress {
  public:
-  explicit SocketAddresses(intptr_t count)
-      : count_(count),
-        addresses_(new SocketAddress*[count_]) {}
+  explicit InterfaceSocketAddress(struct sockaddr* sockaddr,
+                                  const char* interface_name)
+      : socket_address_(new SocketAddress(sockaddr)),
+        interface_name_(interface_name) {}
 
-  ~SocketAddresses() {
+  ~InterfaceSocketAddress() {
+    delete socket_address_;
+    free(const_cast<char*>(interface_name_));
+  }
+
+  SocketAddress* socket_address() const { return socket_address_; }
+  const char* interface_name() const { return interface_name_; }
+
+ private:
+  SocketAddress* socket_address_;
+  const char* interface_name_;
+
+  DISALLOW_COPY_AND_ASSIGN(InterfaceSocketAddress);
+};
+
+template<typename T>
+class AddressList {
+ public:
+  explicit AddressList(intptr_t count)
+      : count_(count),
+        addresses_(new T*[count_]) {}
+
+  ~AddressList() {
     for (intptr_t i = 0; i < count_; i++) {
       delete addresses_[i];
     }
@@ -110,20 +135,22 @@
   }
 
   intptr_t count() const { return count_; }
-  SocketAddress* GetAt(intptr_t i) const { return addresses_[i]; }
-  void SetAt(intptr_t i, SocketAddress* addr) { addresses_[i] = addr; }
+  T* GetAt(intptr_t i) const { return addresses_[i]; }
+  void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; }
 
  private:
   const intptr_t count_;
-  SocketAddress** addresses_;
+  T** addresses_;
 
-  DISALLOW_COPY_AND_ASSIGN(SocketAddresses);
+  DISALLOW_COPY_AND_ASSIGN(AddressList);
 };
 
 class Socket {
  public:
   enum SocketRequest {
     kLookupRequest = 0,
+    kListInterfacesRequest = 1,
+    kReverseLookupRequest = 2,
   };
 
   static bool Initialize();
@@ -144,10 +171,19 @@
   static bool SetBlocking(intptr_t fd);
   static bool SetNoDelay(intptr_t fd, bool enabled);
 
-  // Perform a hostname lookup. Returns the SocketAddresses.
-  static SocketAddresses* LookupAddress(const char* host,
-                                        int type,
-                                        OSError** os_error);
+  // Perform a hostname lookup. Returns a AddressList of SocketAddress's.
+  static AddressList<SocketAddress>* LookupAddress(const char* host,
+                                                   int type,
+                                                   OSError** os_error);
+  static bool ReverseLookup(RawAddr addr,
+                            char* host,
+                            intptr_t host_len,
+                            OSError** os_error);
+
+  // List interfaces. Returns a AddressList of InterfaceSocketAddress's.
+  static AddressList<InterfaceSocketAddress>* ListInterfaces(
+      int type,
+      OSError** os_error);
 
   static Dart_Port GetServicePort();
 
@@ -181,6 +217,7 @@
                                    intptr_t backlog,
                                    bool v6_only = false);
 
+ private:
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket);
 };
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc
index c0fbacd..d837892 100644
--- a/runtime/bin/socket_android.cc
+++ b/runtime/bin/socket_android.cc
@@ -12,6 +12,7 @@
 #include <sys/stat.h>  // NOLINT
 #include <unistd.h>  // NOLINT
 #include <netinet/tcp.h>  // NOLINT
+#include <ifaddrs.h>  // NOLINT
 
 #include "bin/fdutils.h"
 #include "bin/file.h"
@@ -22,17 +23,17 @@
 namespace dart {
 namespace bin {
 
-SocketAddress::SocketAddress(struct addrinfo* addrinfo) {
+SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
   ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
-  RawAddr* raw = reinterpret_cast<RawAddr*>(addrinfo->ai_addr);
-  const char* result = inet_ntop(addrinfo->ai_family,
+  RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
+  const char* result = inet_ntop(sockaddr->sa_family,
                                  &raw->in.sin_addr,
                                  as_string_,
                                  INET6_ADDRSTRLEN);
   if (result == NULL) as_string_[0] = 0;
   memmove(reinterpret_cast<void *>(&addr_),
-          addrinfo->ai_addr,
-          addrinfo->ai_addrlen);
+          sockaddr,
+          GetAddrLength(raw));
 }
 
 
@@ -61,7 +62,7 @@
   intptr_t result = TEMP_FAILURE_RETRY(
       connect(fd,
               &addr.addr,
-              SocketAddress::GetAddrLength(addr)));
+              SocketAddress::GetAddrLength(&addr)));
   if (result == 0 || errno == EINPROGRESS) {
     return fd;
   }
@@ -185,9 +186,9 @@
 }
 
 
-SocketAddresses* Socket::LookupAddress(const char* host,
-                                       int type,
-                                       OSError** os_error) {
+AddressList<SocketAddress>* Socket::LookupAddress(const char* host,
+                                                  int type,
+                                                  OSError** os_error) {
   // Perform a name lookup for a host name.
   struct addrinfo hints;
   memset(&hints, 0, sizeof(hints));
@@ -208,11 +209,11 @@
   for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
     if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++;
   }
-  SocketAddresses* addresses = new SocketAddresses(count);
   intptr_t i = 0;
+  AddressList<SocketAddress>* addresses = new AddressList<SocketAddress>(count);
   for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
     if (c->ai_family == AF_INET || c->ai_family == AF_INET6) {
-      addresses->SetAt(i, new SocketAddress(c));
+      addresses->SetAt(i, new SocketAddress(c->ai_addr));
       i++;
     }
   }
@@ -221,6 +222,77 @@
 }
 
 
+bool Socket::ReverseLookup(RawAddr addr,
+                           char* host,
+                           intptr_t host_len,
+                           OSError** os_error) {
+  ASSERT(host_len >= NI_MAXHOST);
+  int status = TEMP_FAILURE_RETRY(getnameinfo(
+      &addr.addr,
+      SocketAddress::GetAddrLength(&addr),
+      host,
+      host_len,
+      NULL,
+      0,
+      NI_NAMEREQD));
+  if (status != 0) {
+    ASSERT(*os_error == NULL);
+    *os_error = new OSError(status,
+                            gai_strerror(status),
+                            OSError::kGetAddressInfo);
+    return false;
+  }
+  return true;
+}
+
+
+static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
+  int family = ifa->ifa_addr->sa_family;
+  if (lookup_family == family) return true;
+  if (lookup_family == AF_UNSPEC &&
+      (family == AF_INET || family == AF_INET6)) {
+    return true;
+  }
+  return false;
+}
+
+
+AddressList<InterfaceSocketAddress>* Socket::ListInterfaces(
+    int type,
+    OSError** os_error) {
+  struct ifaddrs* ifaddr;
+
+  int status = getifaddrs(&ifaddr);
+  if (status != 0) {
+    ASSERT(*os_error == NULL);
+    *os_error = new OSError(status,
+                            gai_strerror(status),
+                            OSError::kGetAddressInfo);
+    return NULL;
+  }
+
+  int lookup_family = SocketAddress::FromType(type);
+
+  intptr_t count = 0;
+  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+    if (ShouldIncludeIfaAddrs(ifa, lookup_family)) count++;
+  }
+
+  AddressList<InterfaceSocketAddress>* addresses =
+      new AddressList<InterfaceSocketAddress>(count);
+  int i = 0;
+  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+    if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
+      addresses->SetAt(i, new InterfaceSocketAddress(
+          ifa->ifa_addr, strdup(ifa->ifa_name)));
+      i++;
+    }
+  }
+  freeifaddrs(ifaddr);
+  return addresses;
+}
+
+
 intptr_t ServerSocket::CreateBindListen(RawAddr addr,
                                         intptr_t port,
                                         intptr_t backlog,
@@ -246,7 +318,7 @@
   if (TEMP_FAILURE_RETRY(
           bind(fd,
                &addr.addr,
-               SocketAddress::GetAddrLength(addr))) < 0) {
+               SocketAddress::GetAddrLength(&addr))) < 0) {
     TEMP_FAILURE_RETRY(close(fd));
     return -1;
   }
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
index 04ecbe7..3f97475 100644
--- a/runtime/bin/socket_linux.cc
+++ b/runtime/bin/socket_linux.cc
@@ -12,6 +12,7 @@
 #include <sys/stat.h>  // NOLINT
 #include <unistd.h>  // NOLINT
 #include <netinet/tcp.h>  // NOLINT
+#include <ifaddrs.h>  // NOLINT
 
 #include "bin/fdutils.h"
 #include "bin/file.h"
@@ -22,17 +23,17 @@
 namespace dart {
 namespace bin {
 
-SocketAddress::SocketAddress(struct addrinfo* addrinfo) {
+SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
   ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
-  RawAddr* raw = reinterpret_cast<RawAddr*>(addrinfo->ai_addr);
-  const char* result = inet_ntop(addrinfo->ai_family,
+  RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
+  const char* result = inet_ntop(sockaddr->sa_family,
                                  &raw->in.sin_addr,
                                  as_string_,
                                  INET6_ADDRSTRLEN);
   if (result == NULL) as_string_[0] = 0;
   memmove(reinterpret_cast<void *>(&addr_),
-          addrinfo->ai_addr,
-          addrinfo->ai_addrlen);
+          sockaddr,
+          GetAddrLength(raw));
 }
 
 
@@ -61,7 +62,7 @@
   intptr_t result = TEMP_FAILURE_RETRY(
       connect(fd,
               &addr.addr,
-              SocketAddress::GetAddrLength(addr)));
+              SocketAddress::GetAddrLength(&addr)));
   if (result == 0 || errno == EINPROGRESS) {
     return fd;
   }
@@ -184,9 +185,9 @@
 }
 
 
-SocketAddresses* Socket::LookupAddress(const char* host,
-                                       int type,
-                                       OSError** os_error) {
+AddressList<SocketAddress>* Socket::LookupAddress(const char* host,
+                                                  int type,
+                                                  OSError** os_error) {
   // Perform a name lookup for a host name.
   struct addrinfo hints;
   memset(&hints, 0, sizeof(hints));
@@ -207,11 +208,11 @@
   for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
     if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++;
   }
-  SocketAddresses* addresses = new SocketAddresses(count);
   intptr_t i = 0;
+  AddressList<SocketAddress>* addresses = new AddressList<SocketAddress>(count);
   for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
     if (c->ai_family == AF_INET || c->ai_family == AF_INET6) {
-      addresses->SetAt(i, new SocketAddress(c));
+      addresses->SetAt(i, new SocketAddress(c->ai_addr));
       i++;
     }
   }
@@ -220,6 +221,77 @@
 }
 
 
+bool Socket::ReverseLookup(RawAddr addr,
+                           char* host,
+                           intptr_t host_len,
+                           OSError** os_error) {
+  ASSERT(host_len >= NI_MAXHOST);
+  int status = TEMP_FAILURE_RETRY(getnameinfo(
+      &addr.addr,
+      SocketAddress::GetAddrLength(&addr),
+      host,
+      host_len,
+      NULL,
+      0,
+      NI_NAMEREQD));
+  if (status != 0) {
+    ASSERT(*os_error == NULL);
+    *os_error = new OSError(status,
+                            gai_strerror(status),
+                            OSError::kGetAddressInfo);
+    return false;
+  }
+  return true;
+}
+
+
+static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
+  int family = ifa->ifa_addr->sa_family;
+  if (lookup_family == family) return true;
+  if (lookup_family == AF_UNSPEC &&
+      (family == AF_INET || family == AF_INET6)) {
+    return true;
+  }
+  return false;
+}
+
+
+AddressList<InterfaceSocketAddress>* Socket::ListInterfaces(
+    int type,
+    OSError** os_error) {
+  struct ifaddrs* ifaddr;
+
+  int status = getifaddrs(&ifaddr);
+  if (status != 0) {
+    ASSERT(*os_error == NULL);
+    *os_error = new OSError(status,
+                            gai_strerror(status),
+                            OSError::kGetAddressInfo);
+    return NULL;
+  }
+
+  int lookup_family = SocketAddress::FromType(type);
+
+  intptr_t count = 0;
+  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+    if (ShouldIncludeIfaAddrs(ifa, lookup_family)) count++;
+  }
+
+  AddressList<InterfaceSocketAddress>* addresses =
+      new AddressList<InterfaceSocketAddress>(count);
+  int i = 0;
+  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+    if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
+      addresses->SetAt(i, new InterfaceSocketAddress(
+          ifa->ifa_addr, strdup(ifa->ifa_name)));
+      i++;
+    }
+  }
+  freeifaddrs(ifaddr);
+  return addresses;
+}
+
+
 intptr_t ServerSocket::CreateBindListen(RawAddr addr,
                                         intptr_t port,
                                         intptr_t backlog,
@@ -245,7 +317,7 @@
   if (TEMP_FAILURE_RETRY(
           bind(fd,
                &addr.addr,
-               SocketAddress::GetAddrLength(addr))) < 0) {
+               SocketAddress::GetAddrLength(&addr))) < 0) {
     TEMP_FAILURE_RETRY(close(fd));
     return -1;
   }
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index 40b92cf..528f5ab 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -12,6 +12,7 @@
 #include <sys/stat.h>  // NOLINT
 #include <unistd.h>  // NOLINT
 #include <netinet/tcp.h>  // NOLINT
+#include <ifaddrs.h>  // NOLINT
 
 #include "bin/fdutils.h"
 #include "bin/file.h"
@@ -22,17 +23,17 @@
 namespace dart {
 namespace bin {
 
-SocketAddress::SocketAddress(struct addrinfo* addrinfo) {
+SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
   ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
-  RawAddr* raw = reinterpret_cast<RawAddr*>(addrinfo->ai_addr);
-  const char* result = inet_ntop(addrinfo->ai_family,
+  RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
+  const char* result = inet_ntop(sockaddr->sa_family,
                                  &raw->in.sin_addr,
                                  as_string_,
                                  INET6_ADDRSTRLEN);
   if (result == NULL) as_string_[0] = 0;
   memmove(reinterpret_cast<void *>(&addr_),
-          addrinfo->ai_addr,
-          addrinfo->ai_addrlen);
+          sockaddr,
+          GetAddrLength(raw));
 }
 
 
@@ -61,7 +62,7 @@
   intptr_t result = TEMP_FAILURE_RETRY(
       connect(fd,
               &addr.addr,
-              SocketAddress::GetAddrLength(addr)));
+              SocketAddress::GetAddrLength(&addr)));
   if (result == 0 || errno == EINPROGRESS) {
     return fd;
   }
@@ -184,9 +185,9 @@
 }
 
 
-SocketAddresses* Socket::LookupAddress(const char* host,
-                                       int type,
-                                       OSError** os_error) {
+AddressList<SocketAddress>* Socket::LookupAddress(const char* host,
+                                                  int type,
+                                                  OSError** os_error) {
   // Perform a name lookup for a host name.
   struct addrinfo hints;
   memset(&hints, 0, sizeof(hints));
@@ -207,11 +208,11 @@
   for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
     if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++;
   }
-  SocketAddresses* addresses = new SocketAddresses(count);
   intptr_t i = 0;
+  AddressList<SocketAddress>* addresses = new AddressList<SocketAddress>(count);
   for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
     if (c->ai_family == AF_INET || c->ai_family == AF_INET6) {
-      addresses->SetAt(i, new SocketAddress(c));
+      addresses->SetAt(i, new SocketAddress(c->ai_addr));
       i++;
     }
   }
@@ -220,6 +221,77 @@
 }
 
 
+bool Socket::ReverseLookup(RawAddr addr,
+                           char* host,
+                           intptr_t host_len,
+                           OSError** os_error) {
+  ASSERT(host_len >= NI_MAXHOST);
+  int status = TEMP_FAILURE_RETRY(getnameinfo(
+      &addr.addr,
+      SocketAddress::GetAddrLength(&addr),
+      host,
+      host_len,
+      NULL,
+      0,
+      NI_NAMEREQD));
+  if (status != 0) {
+    ASSERT(*os_error == NULL);
+    *os_error = new OSError(status,
+                            gai_strerror(status),
+                            OSError::kGetAddressInfo);
+    return false;
+  }
+  return true;
+}
+
+
+static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
+  int family = ifa->ifa_addr->sa_family;
+  if (lookup_family == family) return true;
+  if (lookup_family == AF_UNSPEC &&
+      (family == AF_INET || family == AF_INET6)) {
+    return true;
+  }
+  return false;
+}
+
+
+AddressList<InterfaceSocketAddress>* Socket::ListInterfaces(
+    int type,
+    OSError** os_error) {
+  struct ifaddrs* ifaddr;
+
+  int status = getifaddrs(&ifaddr);
+  if (status != 0) {
+    ASSERT(*os_error == NULL);
+    *os_error = new OSError(status,
+                            gai_strerror(status),
+                            OSError::kGetAddressInfo);
+    return NULL;
+  }
+
+  int lookup_family = SocketAddress::FromType(type);
+
+  intptr_t count = 0;
+  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+    if (ShouldIncludeIfaAddrs(ifa, lookup_family)) count++;
+  }
+
+  AddressList<InterfaceSocketAddress>* addresses =
+      new AddressList<InterfaceSocketAddress>(count);
+  int i = 0;
+  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+    if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
+      addresses->SetAt(i, new InterfaceSocketAddress(
+          ifa->ifa_addr, strdup(ifa->ifa_name)));
+      i++;
+    }
+  }
+  freeifaddrs(ifaddr);
+  return addresses;
+}
+
+
 intptr_t ServerSocket::CreateBindListen(RawAddr addr,
                                         intptr_t port,
                                         intptr_t backlog,
@@ -245,7 +317,7 @@
   if (TEMP_FAILURE_RETRY(
           bind(fd,
                &addr.addr,
-               SocketAddress::GetAddrLength(addr))) < 0) {
+               SocketAddress::GetAddrLength(&addr))) < 0) {
     VOID_TEMP_FAILURE_RETRY(close(fd));
     return -1;
   }
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index e69dfed..cc0a6e3 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -42,11 +42,25 @@
   }
 }
 
+patch class NetworkInterface {
+  /* patch */ static Future<List<NetworkInterface>> list({
+      bool includeLoopback: false,
+      bool includeLinkLocal: false,
+      InternetAddressType type: InternetAddressType.ANY}) {
+    return _NativeSocket.listInterfaces(includeLoopback: includeLoopback,
+                                        includeLinkLocal: includeLinkLocal,
+                                        type: type);
+  }
+}
+
 class _InternetAddress implements InternetAddress {
   static const int _ADDRESS_LOOPBACK_IP_V4 = 0;
   static const int _ADDRESS_LOOPBACK_IP_V6 = 1;
   static const int _ADDRESS_ANY_IP_V4 = 2;
   static const int _ADDRESS_ANY_IP_V6 = 3;
+  static const int _IPV4_ADDR_OFFSET = 4;
+  static const int _IPV6_ADDR_OFFSET = 8;
+  static const int _IPV6_ADDR_LENGTH = 16;
 
   static _InternetAddress LOOPBACK_IP_V4 =
       new _InternetAddress.fixed(_ADDRESS_LOOPBACK_IP_V4);
@@ -62,6 +76,36 @@
   final String host;
   final Uint8List _sockaddr_storage;
 
+  bool get isLoopback {
+    switch (type) {
+      case InternetAddressType.IP_V4:
+        return _sockaddr_storage[_IPV4_ADDR_OFFSET] == 127;
+
+      case InternetAddressType.IP_V6:
+        for (int i = 0; i < _IPV6_ADDR_LENGTH - 1; i++) {
+          if (_sockaddr_storage[_IPV6_ADDR_OFFSET + i] != 0) return false;
+        }
+        int lastByteIndex = _IPV6_ADDR_OFFSET + _IPV6_ADDR_LENGTH - 1;
+        return _sockaddr_storage[lastByteIndex] == 1;
+    }
+  }
+
+  bool get isLinkLocal {
+    switch (type) {
+      case InternetAddressType.IP_V4:
+        // Checking for 169.254.0.0/16.
+        return _sockaddr_storage[_IPV4_ADDR_OFFSET] == 169 &&
+            _sockaddr_storage[_IPV4_ADDR_OFFSET + 1] == 254;
+
+      case InternetAddressType.IP_V6:
+        // Checking for fe80::/10.
+        return _sockaddr_storage[_IPV6_ADDR_OFFSET] == 0xFE &&
+            (_sockaddr_storage[_IPV6_ADDR_OFFSET + 1] & 0xB0) == 0x80;
+    }
+  }
+
+  Future<InternetAddress> reverse() => _NativeSocket.reverseLookup(this);
+
   _InternetAddress(InternetAddressType this.type,
                    String this.address,
                    String this.host,
@@ -88,6 +132,12 @@
     }
   }
 
+  // Create a clone of this _InternetAddress replacing the host.
+  _InternetAddress _cloneWithNewHost(String host) {
+    return new _InternetAddress(
+        type, address, host, new Uint8List.fromList(_sockaddr_storage));
+  }
+
   String toString() {
     return "InternetAddress('$address', ${type.name})";
   }
@@ -95,6 +145,17 @@
   static Uint8List _fixed(int id) native "InternetAddress_Fixed";
 }
 
+class _NetworkInterface implements NetworkInterface{
+  final String name;
+  final List<InternetAddress> addresses;
+
+  _NetworkInterface(String this.name, List<InternetAddress> this.addresses);
+
+  String toString() {
+    return "NetworkInterface('$name', $addresses)";
+  }
+}
+
 
 // The _NativeSocket class encapsulates an OS socket.
 class _NativeSocket extends NativeFieldWrapperClass1 {
@@ -131,6 +192,8 @@
 
   // Native port messages.
   static const HOST_NAME_LOOKUP = 0;
+  static const LIST_INTERFACES = 1;
+  static const REVERSE_LOOKUP = 2;
 
   // Socket close state
   bool isClosed = false;
@@ -174,6 +237,49 @@
         });
   }
 
+  static Future<InternetAddress> reverseLookup(InternetAddress addr) {
+    ensureSocketService();
+    return socketService.call([REVERSE_LOOKUP, addr._sockaddr_storage])
+        .then((response) {
+          if (isErrorResponse(response)) {
+            throw createError(response, "Failed host name lookup");
+          } else {
+            return addr._cloneWithNewHost(response);
+          }
+        });
+  }
+
+  static Future<List<NetworkInterface>> listInterfaces({
+      bool includeLoopback: false,
+      bool includeLinkLocal: false,
+      InternetAddressType type: InternetAddressType.ANY}) {
+    ensureSocketService();
+    return socketService.call([LIST_INTERFACES, type._value])
+        .then((response) {
+          if (isErrorResponse(response)) {
+            throw createError(response, "Failed listing interfaces");
+          } else {
+            var list = new List<NetworkInterface>();
+            var map = response.skip(1)
+                .fold(new Map<String, List<InternetAddress>>(), (map, result) {
+                  var type = new InternetAddressType._from(result[0]);
+                  var name = result[3];
+                  var address = new _InternetAddress(
+                      type, result[1], "", result[2]);
+                  if (!includeLinkLocal && address.isLinkLocal) return map;
+                  if (!includeLoopback && address.isLoopback) return map;
+                  map.putIfAbsent(name, () => new List<InternetAddress>());
+                  map[name].add(address);
+                  return map;
+                })
+                .forEach((name, addresses) {
+                  list.add(new _NetworkInterface(name, addresses));
+                });
+            return list;
+          }
+        });
+  }
+
   static Future<_NativeSocket> connect(host, int port) {
     return new Future.value(host)
         .then((host) {
@@ -624,6 +730,9 @@
   bool _readEventsEnabled = true;
   bool _writeEventsEnabled = true;
 
+  // Flag to handle Ctrl-D closing of stdio on Mac OS.
+  bool _isMacOSTerminalInput = false;
+
   static Future<RawSocket> connect(host, int port) {
     return _NativeSocket.connect(host, port)
         .then((socket) => new _RawSocket(socket));
@@ -663,7 +772,11 @@
     var native = new _NativeSocket.pipe();
     native.isClosedWrite = true;
     if (fd != null) _getStdioHandle(native, fd);
-    return new _RawSocket(native);
+    var result = new _RawSocket(native);
+    result._isMacOSTerminalInput =
+        Platform.isMacOS &&
+        _StdIOUtils._socketType(result._socket) == _STDIO_HANDLE_TYPE_TERMINAL;
+    return result;
   }
 
   StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent event),
@@ -679,7 +792,21 @@
 
   int available() => _socket.available();
 
-  List<int> read([int len]) => _socket.read(len);
+  List<int> read([int len]) {
+    if (_isMacOSTerminalInput) {
+      var available = available();
+      if (available == 0) return null;
+      var data = _socket.read(len);
+      if (data == null || data.length < available) {
+        // Reading less than available from a Mac OS terminal indicate Ctrl-D.
+        // This is interpreted as read closed.
+        runAsync(() => _controller.add(RawSocketEvent.READ_CLOSED));
+      }
+      return data;
+    } else {
+      return _socket.read(len);
+    }
+  }
 
   int write(List<int> buffer, [int offset, int count]) =>
       _socket.write(buffer, offset, count);
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index 3a3fd9d..f24cfc5 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -16,9 +16,9 @@
 namespace dart {
 namespace bin {
 
-SocketAddress::SocketAddress(struct addrinfo* addrinfo) {
+SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
   ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
-  RawAddr* raw = reinterpret_cast<RawAddr*>(addrinfo->ai_addr);
+  RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
 
   // Clear the port before calling WSAAddressToString as WSAAddressToString
   // includes the port in the formatted string.
@@ -33,8 +33,8 @@
     as_string_[0] = 0;
   }
   memmove(reinterpret_cast<void *>(&addr_),
-          addrinfo->ai_addr,
-          addrinfo->ai_addrlen);
+          sockaddr,
+          SocketAddress::GetAddrLength(raw));
 }
 
 bool Socket::Initialize() {
@@ -142,7 +142,7 @@
   SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
   SOCKET s = handle->socket();
   SocketAddress::SetAddrPort(&addr, port);
-  int status = connect(s, &addr.addr, SocketAddress::GetAddrLength(addr));
+  int status = connect(s, &addr.addr, SocketAddress::GetAddrLength(&addr));
   if (status == SOCKET_ERROR) {
     DWORD rc = WSAGetLastError();
     ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd);
@@ -216,9 +216,9 @@
 }
 
 
-SocketAddresses* Socket::LookupAddress(const char* host,
-                                       int type,
-                                       OSError** os_error) {
+AddressList<SocketAddress>* Socket::LookupAddress(const char* host,
+                                                  int type,
+                                                  OSError** os_error) {
   Initialize();
 
   // Perform a name lookup for a host name.
@@ -241,11 +241,11 @@
   for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
     if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++;
   }
-  SocketAddresses* addresses = new SocketAddresses(count);
+  AddressList<SocketAddress>* addresses = new AddressList<SocketAddress>(count);
   intptr_t i = 0;
   for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
     if (c->ai_family == AF_INET || c->ai_family == AF_INET6) {
-      addresses->SetAt(i, new SocketAddress(c));
+      addresses->SetAt(i, new SocketAddress(c->ai_addr));
       i++;
     }
   }
@@ -254,6 +254,85 @@
 }
 
 
+bool Socket::ReverseLookup(RawAddr addr,
+                           char* host,
+                           intptr_t host_len,
+                           OSError** os_error) {
+  ASSERT(host_len >= NI_MAXHOST);
+  int status = getnameinfo(&addr.addr,
+                           SocketAddress::GetAddrLength(&addr),
+                           host,
+                           host_len,
+                           NULL,
+                           0,
+                           NI_NAMEREQD);
+  if (status != 0) {
+    ASSERT(*os_error == NULL);
+    DWORD error_code = WSAGetLastError();
+    SetLastError(error_code);
+    *os_error = new OSError();
+    return false;
+  }
+  return true;
+}
+
+
+AddressList<InterfaceSocketAddress>* Socket::ListInterfaces(
+    int type,
+    OSError** os_error) {
+  Initialize();
+
+  ULONG size = 0;
+  DWORD flags = GAA_FLAG_SKIP_ANYCAST |
+                GAA_FLAG_SKIP_MULTICAST |
+                GAA_FLAG_SKIP_DNS_SERVER;
+  // Query the size needed.
+  int status = GetAdaptersAddresses(SocketAddress::FromType(type),
+                                    flags,
+                                    NULL,
+                                    NULL,
+                                    &size);
+  IP_ADAPTER_ADDRESSES* addrs = NULL;
+  if (status == ERROR_BUFFER_OVERFLOW) {
+    addrs = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(size));
+    // Get the addresses now we have the right buffer.
+    status = GetAdaptersAddresses(SocketAddress::FromType(type),
+                                  flags,
+                                  NULL,
+                                  addrs,
+                                  &size);
+  }
+  if (status != NO_ERROR) {
+    ASSERT(*os_error == NULL);
+    DWORD error_code = WSAGetLastError();
+    SetLastError(error_code);
+    *os_error = new OSError();
+    return NULL;
+  }
+  intptr_t count = 0;
+  for (IP_ADAPTER_ADDRESSES* a = addrs; a != NULL; a = a->Next) {
+    for (IP_ADAPTER_UNICAST_ADDRESS* u = a->FirstUnicastAddress;
+         u != NULL; u = u->Next) {
+      count++;
+    }
+  }
+  AddressList<InterfaceSocketAddress>* addresses =
+      new AddressList<InterfaceSocketAddress>(count);
+  intptr_t i = 0;
+  for (IP_ADAPTER_ADDRESSES* a = addrs; a != NULL; a = a->Next) {
+    for (IP_ADAPTER_UNICAST_ADDRESS* u = a->FirstUnicastAddress;
+         u != NULL; u = u->Next) {
+      addresses->SetAt(i, new InterfaceSocketAddress(
+          u->Address.lpSockaddr,
+          StringUtils::WideToUtf8(a->FriendlyName)));
+      i++;
+    }
+  }
+  free(addrs);
+  return addresses;
+}
+
+
 intptr_t ServerSocket::CreateBindListen(RawAddr addr,
                                         intptr_t port,
                                         intptr_t backlog,
@@ -288,7 +367,7 @@
   SocketAddress::SetAddrPort(&addr, port);
   status = bind(s,
                 &addr.addr,
-                SocketAddress::GetAddrLength(addr));
+                SocketAddress::GetAddrLength(&addr));
   if (status == SOCKET_ERROR) {
     DWORD rc = WSAGetLastError();
     closesocket(s);
diff --git a/runtime/bin/socket_win.h b/runtime/bin/socket_win.h
index 67c9e7c..76f33fd 100644
--- a/runtime/bin/socket_win.h
+++ b/runtime/bin/socket_win.h
@@ -6,6 +6,7 @@
 #define BIN_SOCKET_WIN_H_
 
 #include <winsock2.h>
+#include <iphlpapi.h>
 #include <ws2tcpip.h>
 #include <mswsock.h>
 
diff --git a/runtime/bin/vmstats_impl.cc b/runtime/bin/vmstats_impl.cc
index b73fe64..b3eebff 100644
--- a/runtime/bin/vmstats_impl.cc
+++ b/runtime/bin/vmstats_impl.cc
@@ -59,7 +59,8 @@
   // TODO(tball): allow host to be specified.
   char* host = const_cast<char*>(DEFAULT_HOST);
   OSError* os_error;
-  SocketAddresses* addresses = Socket::LookupAddress(host, -1, &os_error);
+  AddressList<SocketAddress>* addresses =
+      Socket::LookupAddress(host, -1, &os_error);
   if (addresses == NULL) {
     Log::PrintErr("Failed IP lookup of VmStats host %s: %s\n",
                   host, os_error->message());
@@ -68,6 +69,7 @@
   const intptr_t BACKLOG = 128;  // Default value from HttpServer.dart
   int64_t address = ServerSocket::CreateBindListen(
       addresses->GetAt(0)->addr(), port, BACKLOG);
+  delete addresses;
   if (address < 0) {
     Log::PrintErr("Failed binding VmStats socket: %s:%d\n", host, port);
     return;
diff --git a/runtime/dart-runtime.gyp b/runtime/dart-runtime.gyp
index b00105d..17f9bb3 100644
--- a/runtime/dart-runtime.gyp
+++ b/runtime/dart-runtime.gyp
@@ -11,11 +11,7 @@
     'third_party/jscre/jscre.gypi',
   ],
   'variables': {
-    # TODO(zra): LIB_DIR is not defined by the ninja generator on Windows.
-    # Also, LIB_DIR is not toolset specific on Mac. If we want to do a ninja
-    # build on Windows, or cross-compile on Mac, we'll have to find some other
-    # way of getting generated source files into toolset specific locations.
-    'gen_source_dir': '<(LIB_DIR)',
+    'gen_source_dir': '<(SHARED_INTERMEDIATE_DIR)',
     'version_in_cc_file': 'vm/version_in.cc',
     'version_cc_file': '<(gen_source_dir)/version.cc',
 
@@ -42,7 +38,7 @@
         'libdart_vm',
         'libjscre',
         'libdouble_conversion',
-        'generate_version_cc_file',
+        'generate_version_cc_file#host',
       ],
       'include_dirs': [
         '.',
@@ -72,7 +68,7 @@
     {
       'target_name': 'generate_version_cc_file',
       'type': 'none',
-      'toolsets':['target','host'],
+      'toolsets':['host'],
       'dependencies': [
         'libdart_dependency_helper.target#target',
         'libdart_dependency_helper.host#host',
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index cd09095b..a75932f 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -1142,8 +1142,8 @@
 DART_EXPORT bool Dart_IsExternalString(Dart_Handle object);
 DART_EXPORT bool Dart_IsList(Dart_Handle object);
 DART_EXPORT bool Dart_IsLibrary(Dart_Handle object);
+DART_EXPORT bool Dart_IsType(Dart_Handle handle);
 DART_EXPORT bool Dart_IsClass(Dart_Handle handle);
-DART_EXPORT bool Dart_IsAbstractClass(Dart_Handle handle);
 DART_EXPORT bool Dart_IsFunction(Dart_Handle handle);
 DART_EXPORT bool Dart_IsVariable(Dart_Handle handle);
 DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle);
@@ -1165,6 +1165,18 @@
  * any functions that more properly belong here. */
 
 /**
+ * Gets the type of a Dart language object.
+ *
+ * \param instance Some Dart object.
+ *
+ * \return If no error occurs, the type is returned. Otherwise an
+ *   error handle is returned.
+ */
+DART_EXPORT Dart_Handle Dart_InstanceGetType(Dart_Handle instance);
+
+/**
+ * TODO(asiva): Deprecate this method once all use cases have switched
+ *              to using Dart_InstanceGetType
  * Gets the class for some Dart language object.
  *
  * \param instance Some Dart object.
@@ -1736,7 +1748,7 @@
  * This function allows hidden constructors (constructors with leading
  * underscores) to be called.
  *
- * \param clazz A class or an interface.
+ * \param type Type of object to be constructed.
  * \param constructor_name The name of the constructor to invoke.  Use
  *   Dart_Null() to invoke the unnamed constructor.  This name should
  *   not include the name of the class.
@@ -1747,25 +1759,36 @@
  *   then the new object. If an error occurs during execution, then an
  *   error handle is returned.
  */
-DART_EXPORT Dart_Handle Dart_New(Dart_Handle clazz,
+DART_EXPORT Dart_Handle Dart_New(Dart_Handle type,
                                  Dart_Handle constructor_name,
                                  int number_of_arguments,
                                  Dart_Handle* arguments);
 
 /**
+ * Allocate a new object without invoking a constructor.
+ *
+ * \param type The type of an object to be allocated.
+ *
+ * \return The new object. If an error occurs during execution, then an
+ *   error handle is returned.
+ */
+DART_EXPORT Dart_Handle Dart_Allocate(Dart_Handle type);
+
+/**
  * Invokes a method or function.
  *
- * The 'target' parameter may be an object, class, or library.  If
+ * The 'target' parameter may be an object, type, or library.  If
  * 'target' is an object, then this function will invoke an instance
- * method.  If 'target' is a class, then this function will invoke a
+ * method.  If 'target' is a type, then this function will invoke a
  * static method.  If 'target' is a library, then this function will
  * invoke a top-level function from that library.
+ * NOTE: This API call cannot be used to invoke methods of a type object.
  *
  * This function ignores visibility (leading underscores in names).
  *
  * May generate an unhandled exception error.
  *
- * \param target An object, class, or library.
+ * \param target An object, type, or library.
  * \param name The name of the function or method to invoke.
  * \param number_of_arguments Size of the arguments array.
  * \param arguments An array of arguments to the function.
@@ -1796,17 +1819,18 @@
 /**
  * Gets the value of a field.
  *
- * The 'container' parameter may be an object, class, or library.  If
+ * The 'container' parameter may be an object, type, or library.  If
  * 'container' is an object, then this function will access an
- * instance field.  If 'container' is a class, then this function will
+ * instance field.  If 'container' is a type, then this function will
  * access a static field.  If 'container' is a library, then this
  * function will access a top-level variable.
+ * NOTE: This API call cannot be used to access fields of a type object.
  *
  * This function ignores field visibility (leading underscores in names).
  *
  * May generate an unhandled exception error.
  *
- * \param container An object, class, or library.
+ * \param container An object, type, or library.
  * \param name A field name.
  *
  * \return If no error occurs, then the value of the field is
@@ -1818,17 +1842,18 @@
 /**
  * Sets the value of a field.
  *
- * The 'container' parameter may actually be an object, class, or
+ * The 'container' parameter may actually be an object, type, or
  * library.  If 'container' is an object, then this function will
- * access an instance field.  If 'container' is a class, then this
+ * access an instance field.  If 'container' is a type, then this
  * function will access a static field.  If 'container' is a library,
  * then this function will access a top-level variable.
+ * NOTE: This API call cannot be used to access fields of a type object.
  *
  * This function ignores field visibility (leading underscores in names).
  *
  * May generate an unhandled exception error.
  *
- * \param container An object, class, or library.
+ * \param container An object, type, or library.
  * \param name A field name.
  * \param value The new field value.
  *
@@ -2058,6 +2083,24 @@
 DART_EXPORT Dart_Handle Dart_RootLibrary();
 
 /**
+ * Lookup or instantiate a type by name and type arguments from a Library.
+ *
+ * \param library The library containing the class or interface.
+ * \param class_name The class name for the type.
+ * \param number_of_type_arguments Number of type arguments.
+ *   For non parametric types the number of type arguments would be 0.
+ * \param type_arguments Pointer to an array of type arguments.
+ *   For non parameteric types a NULL would be passed in for this argument.
+ *
+ * \return If no error occurs, the type is returned.
+ *   Otherwise an error handle is returned.
+ */
+DART_EXPORT Dart_Handle Dart_GetType(Dart_Handle library,
+                                     Dart_Handle class_name,
+                                     intptr_t number_of_type_arguments,
+                                     Dart_Handle* type_arguments);
+
+/**
  * Lookup a class or interface by name from a Library.
  *
  * \param library The library containing the class or interface.
@@ -2068,8 +2111,8 @@
  */
 DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library,
                                       Dart_Handle class_name);
-/* TODO(turnidge): Consider returning Dart_Null() when the class is
- * not found to distinguish that from a true error case. */
+/* TODO(asiva): The above method needs to be removed once all uses
+ * of it are removed from the embedder code. */
 
 /**
  * Returns the url from which a library was loaded.
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index cfb640b..e7f88a3 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -118,7 +118,7 @@
 
   // Iterable interface.
 
-  bool contains(E element) {
+  bool contains(Object element) {
     return IterableMixinWorkaround.contains(this, element);
   }
 
@@ -202,11 +202,11 @@
     IterableMixinWorkaround.sortList(this, compare);
   }
 
-  int indexOf(E element, [int start = 0]) {
+  int indexOf(Object element, [int start = 0]) {
     return Arrays.indexOf(this, element, start, this.length);
   }
 
-  int lastIndexOf(E element, [int start = null]) {
+  int lastIndexOf(Object element, [int start = null]) {
     if (start == null) start = length - 1;
     return Arrays.lastIndexOf(this, element, start);
   }
@@ -371,7 +371,7 @@
 
   // Collection interface.
 
-  bool contains(E element) {
+  bool contains(Object element) {
     return IterableMixinWorkaround.contains(this, element);
   }
 
@@ -460,11 +460,11 @@
     return ToString.iterableToString(this);
   }
 
-  int indexOf(E element, [int start = 0]) {
+  int indexOf(Object element, [int start = 0]) {
     return Arrays.indexOf(this, element, start, this.length);
   }
 
-  int lastIndexOf(E element, [int start = null]) {
+  int lastIndexOf(Object element, [int start = null]) {
     if (start == null) start = length - 1;
     return Arrays.lastIndexOf(this, element, start);
   }
diff --git a/runtime/lib/collection_patch.dart b/runtime/lib/collection_patch.dart
index 6479ba2..415982c 100644
--- a/runtime/lib/collection_patch.dart
+++ b/runtime/lib/collection_patch.dart
@@ -9,11 +9,11 @@
     _hashTable._container = this;
   }
 
-  /* patch */ bool containsKey(K key) {
+  /* patch */ bool containsKey(Object key) {
     return _hashTable._get(key) >= 0;
   }
 
-  /* patch */ bool containsValue(V value) {
+  /* patch */ bool containsValue(Object value) {
     List table = _hashTable._table;
     int entrySize = _hashTable._entrySize;
     for (int offset = 0; offset < table.length; offset += entrySize) {
@@ -33,7 +33,7 @@
     });
   }
 
-  /* patch */ V operator [](K key) {
+  /* patch */ V operator [](Object key) {
     int offset = _hashTable._get(key);
     if (offset >= 0) return _hashTable._value(offset);
     return null;
@@ -74,7 +74,7 @@
     return value;
   }
 
-  /* patch */ V remove(K key) {
+  /* patch */ V remove(Object key) {
     int offset = _hashTable._remove(key);
     if (offset < 0) return null;
     V oldValue = _hashTable._value(offset);
@@ -203,11 +203,11 @@
     _hashTable._container = this;
   }
 
-  /* patch */ bool containsKey(K key) {
+  /* patch */ bool containsKey(Object key) {
     return _hashTable._get(key) >= 0;
   }
 
-  /* patch */ bool containsValue(V value) {
+  /* patch */ bool containsValue(Object value) {
     int modificationCount = _hashTable._modificationCount;
     for (int offset = _hashTable._next(_LinkedHashTable._HEAD_OFFSET);
          offset != _LinkedHashTable._HEAD_OFFSET;
@@ -229,7 +229,7 @@
     });
   }
 
-  /* patch */ V operator [](K key) {
+  /* patch */ V operator [](Object key) {
     int offset = _hashTable._get(key);
     if (offset >= 0) return _hashTable._value(offset);
     return null;
@@ -271,7 +271,7 @@
     return value;
   }
 
-  /* patch */ V remove(K key) {
+  /* patch */ V remove(Object key) {
     int offset = _hashTable._remove(key);
     if (offset < 0) return null;
     Object oldValue = _hashTable._value(offset);
@@ -644,7 +644,7 @@
   /**
    * Returns the offset of a key in [_table], or negative if it's not there.
    */
-  int _get(K key) {
+  int _get(Object key) {
     return _probeForLookup(_hashCodeOf(key), key);
   }
 
@@ -678,7 +678,7 @@
    * If [_entrySize] is greater than 1, the caller should clean up the
    * remaining fields.
    */
-  int _remove(K key) {
+  int _remove(Object key) {
     int offset = _probeForLookup(_hashCodeOf(key), key);
     if (offset >= 0) {
       _deleteEntry(offset);
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index daf8f01..f52ff8f 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -169,3 +169,10 @@
     return msg_buf.toString();
   }
 }
+
+class _FiftyThreeBitOverflowError implements Error {
+  final Object _value;
+
+  const _FiftyThreeBitOverflowError(this._value);
+  String toString() => "53-bit Overflow: $_value";
+}
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 6dfb6f6..d58492e 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -212,11 +212,11 @@
     throw new StateError("More than one element");
   }
 
-  int indexOf(T element, [int start = 0]) {
+  int indexOf(Object element, [int start = 0]) {
     return IterableMixinWorkaround.indexOfList(this, element, start);
   }
 
-  int lastIndexOf(T element, [int start = null]) {
+  int lastIndexOf(Object element, [int start = null]) {
     return IterableMixinWorkaround.lastIndexOfList(this, element, start);
   }
 
@@ -230,7 +230,7 @@
 
   // Collection interface.
 
-  bool contains(T element) {
+  bool contains(Object element) {
     return IterableMixinWorkaround.contains(this, element);
   }
 
diff --git a/runtime/lib/immutable_map.dart b/runtime/lib/immutable_map.dart
index 3c5c72e..77127e5 100644
--- a/runtime/lib/immutable_map.dart
+++ b/runtime/lib/immutable_map.dart
@@ -10,7 +10,7 @@
       : kvPairs_ = keyValuePairs;
 
 
-  V operator [](K key) {
+  V operator [](Object key) {
     // TODO(hausner): Since the keys are sorted, we could do a binary
     // search. But is it worth it?
     for (int i = 0; i < kvPairs_.length - 1; i += 2) {
@@ -45,7 +45,7 @@
     return new _ImmutableMapValueIterable<V>(this);
   }
 
-  bool containsKey(K key) {
+  bool containsKey(Object key) {
     for (int i = 0; i < kvPairs_.length; i += 2) {
       if (key == kvPairs_[i]) {
         return true;
@@ -54,7 +54,7 @@
     return false;
   }
 
-  bool containsValue(V value) {
+  bool containsValue(Object value) {
     for (int i = 1; i < kvPairs_.length; i += 2) {
       if (value == kvPairs_[i]) {
         return true;
@@ -75,7 +75,7 @@
     throw new UnsupportedError("Cannot clear unmodifiable Map");
   }
 
-  V remove(K key) {
+  V remove(Object key) {
     throw new UnsupportedError("Cannot remove from unmodifiable Map");
   }
 
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index 80b369c..2d40f2d 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -129,11 +129,14 @@
     return _substringMatches(this.length - other.length, other);
   }
 
-  bool startsWith(Pattern pattern) {
-    if (pattern is String) {
-      return _substringMatches(0, pattern);
+  bool startsWith(Pattern pattern, [int index = 0]) {
+    if (index < 0 || index > this.length) {
+      throw new RangeError.range(index, 0, this.length);
     }
-    return pattern.matchAsPrefix(this, 0) != null;
+    if (pattern is String) {
+      return _substringMatches(index, pattern);
+    }
+    return pattern.matchAsPrefix(this, index) != null;
   }
 
   int indexOf(Pattern pattern, [int start = 0]) {
diff --git a/runtime/tests/vm/dart/byte_array_optimized_test.dart b/runtime/tests/vm/dart/byte_array_optimized_test.dart
index fafef82..8492798 100644
--- a/runtime/tests/vm/dart/byte_array_optimized_test.dart
+++ b/runtime/tests/vm/dart/byte_array_optimized_test.dart
@@ -1,6 +1,7 @@
 // Copyright (c) 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.
+// VMOptions=--optimization_counter_threshold=10
 
 // Library tag to be able to run in html test framework.
 library byte_array_test;
@@ -2129,7 +2130,7 @@
 }
 
 main() {
-  for (var i=0; i<1000; i++) {
+  for (var i=0; i<20; i++) {
     OptimizedByteArrayTest.testMain();
   }
 }
diff --git a/runtime/tests/vm/dart/byte_array_test.dart b/runtime/tests/vm/dart/byte_array_test.dart
index 0f3fe96..19fecb3 100644
--- a/runtime/tests/vm/dart/byte_array_test.dart
+++ b/runtime/tests/vm/dart/byte_array_test.dart
@@ -1,6 +1,7 @@
 // Copyright (c) 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.
+// VMOptions=--optimization_counter_threshold=10
 
 // Library tag to be able to run in html test framework.
 library byte_array_test;
@@ -2380,7 +2381,7 @@
 }
 
 main() {
-  for (var i=0; i<1000; i++) {
+  for (var i=0; i<20; i++) {
     ByteArrayTest.testMain();
   }
 }
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 2319452..8f82b99 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -54,30 +54,19 @@
 # Skip until we stabilize language tests.
 *: Skip
 
-[ $arch == simarm || $arch == arm ]
-# Bug in optimized code generation results in timeout.
-dart/byte_array_test: Skip
-dart/byte_array_optimized_test: Skip
-
-[ $arch == arm ]
-cc/DoubleToFloatConversion: Fail # Issue: 11207
-cc/DoubleToIntConversion: Fail # Issue: 11207
-cc/FloatToDoubleConversion: Fail # Issue: 11207
-cc/FloatToIntConversion: Fail # Issue: 11207
-cc/IntToDoubleConversion: Fail # Issue: 11207
-cc/IntToFloatConversion: Fail # Issue: 11207
+[ $arch == arm && $mode == release ]
+dart/byte_array_optimized_test: Crash
+dart/byte_array_test: Crash
 
 [ $arch == mips ]
 *: Skip
 
-[ $arch == simmips ]
-# Tests missing code generation support.
-dart/byte_array_test: Skip
-dart/byte_array_optimized_test: Skip
+[ $arch == simarm ]
 dart/isolate_mirror_local_test: Skip
-cc/ParsePatchLibrary: Skip
-cc/CorelibCompileAll: Skip
-cc/Dart2JSCompileAll: Skip
+
+[ $arch == simmips ]
+dart/isolate_mirror_local_test: Pass, Crash
+cc/FindCodeObject: Skip #  Relative offsets are too far
 
 # TODO(ajohnsen): Fix this as part of library changes.
 [ $compiler == none ]
@@ -92,4 +81,3 @@
 [ $compiler == dart2analyzer ]
 # has compilation error, as designed
 dart/isolate_mirror_local_test: fail
-
diff --git a/runtime/vm/assembler_arm_test.cc b/runtime/vm/assembler_arm_test.cc
index 9e54e5a..4e31ae0 100644
--- a/runtime/vm/assembler_arm_test.cc
+++ b/runtime/vm/assembler_arm_test.cc
@@ -189,7 +189,6 @@
   __ vsubs(S0, S0, S1);  // 49.98f
   __ vdivs(S0, S0, S1);  // 14.7f
   __ vsqrts(S0, S0);  // 3.8340579f
-  __ vmovrs(R0, S0);
   __ bx(LR);
 }
 
@@ -212,7 +211,6 @@
   __ vsubd(D0, D0, D1);  // 49.98
   __ vdivd(D0, D0, D1);  // 14.7
   __ vsqrtd(D0, D0);  // 3.8340579
-  __ vmovrrd(R0, R1, D0);
   __ bx(LR);
 }
 
@@ -247,8 +245,7 @@
 ASSEMBLER_TEST_GENERATE(IntToDoubleConversion, assembler) {
   __ mov(R3, ShifterOperand(6));
   __ vmovsr(S3, R3);
-  __ vcvtdi(D1, S3);
-  __ vmovrrd(R0, R1, D1);
+  __ vcvtdi(D0, S3);
   __ bx(LR);
 }
 
@@ -272,7 +269,6 @@
   __ vcvtdi(D1, S2);
   __ LoadDImmediate(D2, 1.0 * (1LL << 32), R0);
   __ vmlad(D0, D1, D2);
-  __ vmovrrd(R0, R1, D0);
   __ bx(LR);
 }
 
@@ -289,8 +285,7 @@
 ASSEMBLER_TEST_GENERATE(IntToFloatConversion, assembler) {
   __ mov(R3, ShifterOperand(6));
   __ vmovsr(S3, R3);
-  __ vcvtsi(S1, S3);
-  __ vmovrs(R0, S1);
+  __ vcvtsi(S0, S3);
   __ bx(LR);
 }
 
@@ -304,9 +299,8 @@
 
 
 ASSEMBLER_TEST_GENERATE(FloatToIntConversion, assembler) {
-  __ vmovsr(S1, R0);
-  __ vcvtis(S0, S1);
-  __ vmovrs(R0, S0);
+  __ vcvtis(S1, S0);
+  __ vmovrs(R0, S1);
   __ bx(LR);
 }
 
@@ -327,8 +321,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(DoubleToIntConversion, assembler) {
-  __ vmovdrr(D1, R0, R1);
-  __ vcvtid(S0, D1);
+  __ vcvtid(S0, D0);
   __ vmovrs(R0, S0);
   __ bx(LR);
 }
@@ -350,9 +343,8 @@
 
 
 ASSEMBLER_TEST_GENERATE(FloatToDoubleConversion, assembler) {
-  __ LoadSImmediate(S1, 12.8f);
-  __ vcvtds(D2, S1);
-  __ vmovrrd(R0, R1, D2);
+  __ LoadSImmediate(S2, 12.8f);
+  __ vcvtds(D0, S2);
   __ bx(LR);
 }
 
@@ -368,8 +360,7 @@
 
 ASSEMBLER_TEST_GENERATE(DoubleToFloatConversion, assembler) {
   __ LoadDImmediate(D1, 12.8, R0);
-  __ vcvtsd(S3, D1);
-  __ vmovrs(R0, S3);
+  __ vcvtsd(S0, D1);
   __ bx(LR);
 }
 
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 0b74365..b94675a 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -138,7 +138,6 @@
  public:
   static void InitOnce() { }
   static bool double_truncate_round_supported() {
-    UNIMPLEMENTED();
     return false;
   }
 };
@@ -461,6 +460,11 @@
     EmitFpuRType(COP1, FMT_L, F0, fs, fd, COP1_CVT_D);
   }
 
+  void cvtsd(FRegister fd, DRegister ds) {
+    FRegister fs = static_cast<FRegister>(ds * 2);
+    EmitFpuRType(COP1, FMT_D, F0, fs, fd, COP1_CVT_S);
+  }
+
   void cvtwd(FRegister fd, DRegister ds) {
     FRegister fs = static_cast<FRegister>(ds * 2);
     EmitFpuRType(COP1, FMT_D, F0, fs, fd, COP1_CVT_W);
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index 3152e4a..0e9185a 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -192,36 +192,6 @@
 }
 
 
-ASSEMBLER_TEST_GENERATE(Divu_zero, assembler) {
-  __ addiu(R1, ZR, Immediate(27));
-  __ addiu(R2, ZR, Immediate(0));
-  __ divu(R1, R2);
-  __ mflo(V0);
-  __ jr(RA);
-}
-
-
-ASSEMBLER_TEST_RUN(Divu_zero, test) {
-  typedef int (*SimpleCode)();
-  EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
-}
-
-
-ASSEMBLER_TEST_GENERATE(Div_zero, assembler) {
-  __ addiu(R1, ZR, Immediate(27));
-  __ addiu(R2, ZR, Immediate(0));
-  __ div(R1, R2);
-  __ mflo(V0);
-  __ jr(RA);
-}
-
-
-ASSEMBLER_TEST_RUN(Div_zero, test) {
-  typedef int (*SimpleCode)();
-  EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
-}
-
-
 ASSEMBLER_TEST_GENERATE(Divu_corner, assembler) {
   __ LoadImmediate(R1, 0x80000000);
   __ LoadImmediate(R2, 0xffffffff);
@@ -1217,25 +1187,24 @@
 
 ASSEMBLER_TEST_GENERATE(Mtc1Mfc1, assembler) {
   __ mtc1(ZR, F0);
+  __ mtc1(ZR, F1);
   __ mfc1(V0, F0);
+  __ mfc1(V1, F1);
   __ Ret();
 }
 
 
 ASSEMBLER_TEST_RUN(Mtc1Mfc1, test) {
-  typedef double (*SimpleCode)();
+  typedef int (*SimpleCode)();
   EXPECT(test != NULL);
-  double res = EXECUTE_TEST_CODE_FLOAT(SimpleCode, test->entry());
-  EXPECT_FLOAT_EQ(0.0, res, 0.001);
+  EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
 }
 
 
 ASSEMBLER_TEST_GENERATE(Addd, assembler) {
   __ LoadImmediate(D0, 1.0);
   __ LoadImmediate(D1, 2.0);
-  __ addd(D2, D0, D1);
-  __ mfc1(V0, F4);
-  __ mfc1(V1, F5);
+  __ addd(D0, D0, D1);
   __ Ret();
 }
 
@@ -1249,10 +1218,8 @@
 
 
 ASSEMBLER_TEST_GENERATE(Movd, assembler) {
-  __ LoadImmediate(D0, 1.0);
-  __ movd(D1, D0);
-  __ mfc1(V0, F2);
-  __ mfc1(V1, F3);
+  __ LoadImmediate(D1, 1.0);
+  __ movd(D0, D1);
   __ Ret();
 }
 
@@ -1269,11 +1236,9 @@
   __ AddImmediate(SP, -8 * kWordSize);
   __ LoadImmediate(T1, ~(8 - 1));
   __ and_(T0, SP, T1);  // Need 8 byte alignment.
-  __ LoadImmediate(D0, 1.0);
-  __ sdc1(D0, Address(T0));
-  __ ldc1(D1, Address(T0));
-  __ mfc1(V0, F2);
-  __ mfc1(V1, F3);
+  __ LoadImmediate(D1, 1.0);
+  __ sdc1(D1, Address(T0));
+  __ ldc1(D0, Address(T0));
   __ Ret();
 }
 
@@ -1292,9 +1257,7 @@
   __ LoadImmediate(T0, 0x7FF80000);
   __ mtc1(ZR, F2);  // Load upper bits of NaN.
   __ mtc1(T0, F3);  // Load lower bits of NaN.
-  __ addd(D2, D0, D1);
-  __ mfc1(V0, F4);
-  __ mfc1(V1, F5);
+  __ addd(D0, D0, D1);
   __ Ret();
 }
 
@@ -1312,9 +1275,7 @@
   __ LoadImmediate(T0, 0x7FF00000);  // +inf
   __ mtc1(ZR, F2);
   __ mtc1(T0, F3);
-  __ addd(D2, D0, D1);
-  __ mfc1(V0, F4);
-  __ mfc1(V1, F5);
+  __ addd(D0, D0, D1);
   __ Ret();
 }
 
@@ -1330,9 +1291,7 @@
 ASSEMBLER_TEST_GENERATE(Subd, assembler) {
   __ LoadImmediate(D0, 2.5);
   __ LoadImmediate(D1, 1.5);
-  __ subd(D2, D0, D1);
-  __ mfc1(V0, F4);
-  __ mfc1(V1, F5);
+  __ subd(D0, D0, D1);
   __ Ret();
 }
 
@@ -1348,9 +1307,7 @@
 ASSEMBLER_TEST_GENERATE(Muld, assembler) {
   __ LoadImmediate(D0, 6.0);
   __ LoadImmediate(D1, 7.0);
-  __ muld(D2, D0, D1);
-  __ mfc1(V0, F4);
-  __ mfc1(V1, F5);
+  __ muld(D0, D0, D1);
   __ Ret();
 }
 
@@ -1366,9 +1323,7 @@
 ASSEMBLER_TEST_GENERATE(Divd, assembler) {
   __ LoadImmediate(D0, 42.0);
   __ LoadImmediate(D1, 7.0);
-  __ divd(D2, D0, D1);
-  __ mfc1(V0, F4);
-  __ mfc1(V1, F5);
+  __ divd(D0, D0, D1);
   __ Ret();
 }
 
@@ -1382,10 +1337,8 @@
 
 
 ASSEMBLER_TEST_GENERATE(Sqrtd, assembler) {
-  __ LoadImmediate(D0, 36.0);
-  __ sqrtd(D2, D0);
-  __ mfc1(V0, F4);
-  __ mfc1(V1, F5);
+  __ LoadImmediate(D1, 36.0);
+  __ sqrtd(D0, D1);
   __ Ret();
 }
 
@@ -1602,10 +1555,8 @@
 
 ASSEMBLER_TEST_GENERATE(Cop1CvtDW, assembler) {
   __ LoadImmediate(T0, 42);
-  __ mtc1(T0, F0);
-  __ cvtdw(D1, F0);
-  __ mfc1(V0, F2);
-  __ mfc1(V1, F3);
+  __ mtc1(T0, F2);
+  __ cvtdw(D0, F2);
   __ Ret();
 }
 
@@ -1620,10 +1571,8 @@
 
 ASSEMBLER_TEST_GENERATE(Cop1CvtDW_neg, assembler) {
   __ LoadImmediate(T0, -42);
-  __ mtc1(T0, F0);
-  __ cvtdw(D1, F0);
-  __ mfc1(V0, F2);
-  __ mfc1(V1, F3);
+  __ mtc1(T0, F2);
+  __ cvtdw(D0, F2);
   __ Ret();
 }
 
@@ -1638,11 +1587,9 @@
 
 ASSEMBLER_TEST_GENERATE(Cop1CvtDL, assembler) {
   __ LoadImmediate(T0, 0x1);
-  __ mtc1(ZR, F0);
-  __ mtc1(T0, F1);  // D0 <- 0x100000000 = 4294967296
-  __ cvtdl(D1, D0);
-  __ mfc1(V0, F2);
-  __ mfc1(V1, F3);
+  __ mtc1(ZR, F2);
+  __ mtc1(T0, F3);  // D0 <- 0x100000000 = 4294967296
+  __ cvtdl(D0, D1);
   __ Ret();
 }
 
@@ -1657,11 +1604,9 @@
 
 ASSEMBLER_TEST_GENERATE(Cop1CvtDL_neg, assembler) {
   __ LoadImmediate(T0, 0xffffffff);
-  __ mtc1(T0, F0);
-  __ mtc1(T0, F1);  // D0 <- 0xffffffffffffffff = -1
-  __ cvtdl(D1, D0);
-  __ mfc1(V0, F2);
-  __ mfc1(V1, F3);
+  __ mtc1(T0, F2);
+  __ mtc1(T0, F3);  // D0 <- 0xffffffffffffffff = -1
+  __ cvtdl(D0, D1);;
   __ Ret();
 }
 
@@ -1675,35 +1620,51 @@
 
 
 ASSEMBLER_TEST_GENERATE(Cop1CvtWD, assembler) {
-  __ LoadImmediate(D0, 42.0);
-  __ cvtwd(F2, D0);
-  __ mfc1(V0, F2);
+  __ LoadImmediate(D1, 42.0);
+  __ cvtwd(F0, D1);
+  __ mfc1(V0, F0);
   __ Ret();
 }
 
 
 ASSEMBLER_TEST_RUN(Cop1CvtWD, test) {
-  typedef double (*SimpleCode)();
+  typedef int (*SimpleCode)();
   EXPECT(test != NULL);
   EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
 }
 
 
 ASSEMBLER_TEST_GENERATE(Cop1CvtWD_neg, assembler) {
-  __ LoadImmediate(D0, -42.0);
-  __ cvtwd(F2, D0);
-  __ mfc1(V0, F2);
+  __ LoadImmediate(D1, -42.0);
+  __ cvtwd(F0, D1);
+  __ mfc1(V0, F0);
   __ Ret();
 }
 
 
 ASSEMBLER_TEST_RUN(Cop1CvtWD_neg, test) {
-  typedef double (*SimpleCode)();
+  typedef int (*SimpleCode)();
   EXPECT(test != NULL);
   EXPECT_EQ(-42, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
 }
 
 
+ASSEMBLER_TEST_GENERATE(Cop1CvtSD, assembler) {
+  __ LoadImmediate(D2, -42.42);
+  __ cvtsd(F2, D2);
+  __ cvtds(D0, F2);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(Cop1CvtSD, test) {
+  typedef double (*SimpleCode)();
+  EXPECT(test != NULL);
+  double res = EXECUTE_TEST_CODE_DOUBLE(SimpleCode, test->entry());
+  EXPECT_FLOAT_EQ(-42.42, res, 0.001);
+}
+
+
 // Called from assembler_test.cc.
 // RA: return address.
 // A0: context.
diff --git a/runtime/vm/base_isolate.h b/runtime/vm/base_isolate.h
index 687054f..e445209 100644
--- a/runtime/vm/base_isolate.h
+++ b/runtime/vm/base_isolate.h
@@ -95,6 +95,16 @@
   }
 
 #if defined(DEBUG)
+  void set_reusable_handle_scope_active(bool value) {
+    reusable_handle_scope_active_ = value;
+  }
+
+  bool reusable_handle_scope_active() {
+    return reusable_handle_scope_active_;
+  }
+#endif
+
+#if defined(DEBUG)
   static void AssertCurrent(BaseIsolate* isolate);
 #endif
 
@@ -106,6 +116,7 @@
         top_handle_scope_(NULL),
         no_handle_scope_depth_(0),
         no_gc_scope_depth_(0),
+        reusable_handle_scope_active_(false),
 #endif
         no_callback_scope_depth_(0)
   {}
@@ -120,9 +131,11 @@
   HandleScope* top_handle_scope_;
   int32_t no_handle_scope_depth_;
   int32_t no_gc_scope_depth_;
+  bool reusable_handle_scope_active_;
 #endif
   int32_t no_callback_scope_depth_;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(BaseIsolate);
 };
 
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 9fff0d7..4b95263 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -957,7 +957,8 @@
     function = super_class.LookupFunction(name);
     if (!function.IsNull() &&
         !function.is_static() &&
-        !function.IsMethodExtractor()) {
+        !function.IsMethodExtractor() &&
+        !function.IsNoSuchMethodDispatcher()) {
       return super_class.raw();
     }
     super_class = super_class.SuperClass();
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index 88b5b76..2f08ac3 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -44,7 +44,7 @@
   test->node_sequence()->Add(new ReturnNode(kPos, l));
   parsed_function->SetNodeSequence(test->node_sequence());
   parsed_function->set_instantiator(NULL);
-  parsed_function->set_default_parameter_values(Array::ZoneHandle());
+  parsed_function->set_default_parameter_values(Object::null_array());
   parsed_function->AllocateVariables();
   bool retval;
   Isolate* isolate = Isolate::Current();
@@ -259,7 +259,7 @@
       PcDescriptors::Handle(code.pc_descriptors());
   int call_count = 0;
   for (int i = 0; i < descriptors.Length(); ++i) {
-    if (descriptors.DescriptorKind(i) == PcDescriptors::kFuncCall) {
+    if (descriptors.DescriptorKind(i) == PcDescriptors::kUnoptStaticCall) {
       stackmap_table_builder->AddEntry(descriptors.PC(i) - code.EntryPoint(),
                                        stack_bitmap,
                                        0);
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 6eec38d..91ed8eb 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -38,7 +38,7 @@
     "Trace IC miss in optimized code");
 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code.");
 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls");
-DEFINE_FLAG(int, optimization_counter_threshold, 3000,
+DEFINE_FLAG(int, optimization_counter_threshold, 15000,
     "Function's usage-counter value before it is optimized, -1 means never");
 DECLARE_FLAG(bool, enable_type_checks);
 DECLARE_FLAG(bool, trace_type_checks);
@@ -729,8 +729,8 @@
 }
 
 
-// Patches static call with the target's entry point. Compiles target if
-// necessary.
+// Patches static call in optimized code with the target's entry point.
+// Compiles target if necessary.
 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) {
   ASSERT(arguments.ArgCount() == kPatchStaticCallRuntimeEntry.argument_count());
   DartFrameIterator iterator;
@@ -738,6 +738,7 @@
   ASSERT(caller_frame != NULL);
   const Code& caller_code = Code::Handle(caller_frame->LookupDartCode());
   ASSERT(!caller_code.IsNull());
+  ASSERT(caller_code.is_optimized());
   const Function& target_function = Function::Handle(
       caller_code.GetStaticCallTargetFunctionAt(caller_frame->pc()));
   if (!target_function.HasCode()) {
@@ -768,11 +769,10 @@
 // Resolves and compiles the target function of an instance call, updates
 // function cache of the receiver's class and returns the compiled code or null.
 // Only the number of named arguments is checked, but not the actual names.
-RawCode* ResolveCompileInstanceCallTarget(
-    const Instance& receiver,
-    const ICData& ic_data,
-    const Array& arguments_descriptor_array) {
-  ArgumentsDescriptor arguments_descriptor(arguments_descriptor_array);
+RawCode* ResolveCompileInstanceCallTarget(const Instance& receiver,
+                                          const ICData& ic_data) {
+  ArgumentsDescriptor
+      arguments_descriptor(Array::Handle(ic_data.arguments_descriptor()));
   intptr_t num_arguments = arguments_descriptor.Count();
   int num_named_arguments = arguments_descriptor.NamedCount();
   String& function_name = String::Handle(ic_data.target_name());
@@ -836,8 +836,10 @@
   StackFrame* caller_frame = iterator.NextFrame();
   ASSERT(caller_frame != NULL);
   const Code& code = Code::Handle(caller_frame->LookupDartCode());
+  ASSERT(!code.is_optimized());
   const Function& function =
-      Function::Handle(code.GetStaticCallTargetFunctionAt(caller_frame->pc()));
+      Function::Handle(CodePatcher::GetUnoptimizedStaticCallAt(
+          caller_frame->pc(), code, NULL));
 
   if (!function.HasCode()) {
     const Error& error = Error::Handle(Compiler::CompileFunction(function));
@@ -871,18 +873,17 @@
 static RawFunction* InlineCacheMissHandler(
     const GrowableArray<const Instance*>& args,
     const ICData& ic_data,
-    const Array& arg_descriptor_array) {
+    const Array& args_descriptor_array) {
   const Instance& receiver = *args[0];
   const Code& target_code =
-      Code::Handle(ResolveCompileInstanceCallTarget(receiver,
-                                                    ic_data,
-                                                    arg_descriptor_array));
+      Code::Handle(ResolveCompileInstanceCallTarget(receiver, ic_data));
   if (target_code.IsNull()) {
     // Let the megamorphic stub handle special cases: NoSuchMethod,
     // closure calls.
     if (FLAG_trace_ic) {
-      OS::PrintErr("InlineCacheMissHandler NULL code for receiver: %s\n",
-          receiver.ToCString());
+      OS::PrintErr("InlineCacheMissHandler NULL code for %s receiver: %s\n",
+                   String::Handle(ic_data.target_name()).ToCString(),
+                   receiver.ToCString());
     }
     return Function::null();
   }
@@ -1157,7 +1158,9 @@
                                                getter_name,
                                                kNumArguments,
                                                kNumNamedArguments));
-  if (getter.IsNull() || getter.IsMethodExtractor()) {
+  if (getter.IsNull() ||
+      getter.IsMethodExtractor() ||
+      getter.IsNoSuchMethodDispatcher()) {
     return false;
   }
 
@@ -1182,6 +1185,41 @@
 }
 
 
+// Create a method for noSuchMethod invocation and attach it to the receiver
+// class.
+static RawFunction* CreateNoSuchMethodDispatcher(
+    const String& target_name,
+    const Class& receiver_class,
+    const Array& arguments_descriptor) {
+  Function& invocation = Function::Handle(
+      Function::New(String::Handle(Symbols::New(target_name)),
+                    RawFunction::kNoSuchMethodDispatcher,
+                    false,  // Not static.
+                    false,  // Not const.
+                    false,  // Not abstract.
+                    false,  // Not external.
+                    receiver_class,
+                    0));  // No token position.
+
+  // Initialize signature: receiver is a single fixed parameter.
+  const intptr_t kNumParameters = 1;
+  invocation.set_num_fixed_parameters(kNumParameters);
+  invocation.SetNumOptionalParameters(0, 0);
+  invocation.set_parameter_types(Array::Handle(Array::New(kNumParameters,
+                                                         Heap::kOld)));
+  invocation.set_parameter_names(Array::Handle(Array::New(kNumParameters,
+                                                         Heap::kOld)));
+  invocation.SetParameterTypeAt(0, Type::Handle(Type::DynamicType()));
+  invocation.SetParameterNameAt(0, Symbols::This());
+  invocation.set_result_type(Type::Handle(Type::DynamicType()));
+  invocation.set_is_visible(false);  // Not visible in stack trace.
+
+  receiver_class.AddFunction(invocation);
+
+  return invocation.raw();
+}
+
+
 // The IC miss handler has failed to find a (cacheable) instance function to
 // invoke.  Handle three possibilities:
 //
@@ -1216,16 +1254,78 @@
                                 args_descriptor,
                                 args,
                                 &result)) {
-    result = DartEntry::InvokeNoSuchMethod(receiver,
-                                           target_name,
-                                           args,
-                                           args_descriptor);
+    ArgumentsDescriptor desc(args_descriptor);
+    Function& target_function = Function::Handle(
+        Resolver::ResolveDynamicAnyArgs(receiver_class, target_name));
+    // Check number of arguments and check that there is not already a method
+    // with the same name present.
+    // TODO(fschneider): Handle multiple arguments.
+    if (target_function.IsNull() &&
+        (desc.Count() == 1) && (desc.PositionalCount() == 1)) {
+      // Create Function for noSuchMethodInvocation and add it to the class.
+      target_function ^= CreateNoSuchMethodDispatcher(target_name,
+                                                      receiver_class,
+                                                      args_descriptor);
+
+      // Update IC data.
+      ASSERT(!target_function.IsNull());
+      ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
+      if (FLAG_trace_ic) {
+        OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%"Pd" -> <%s>\n",
+            Class::Handle(receiver.clazz()).ToCString(),
+            receiver.GetClassId(),
+            target_function.ToCString());
+      }
+      result =
+          DartEntry::InvokeFunction(target_function, args, args_descriptor);
+    } else {
+      result = DartEntry::InvokeNoSuchMethod(receiver,
+                                             target_name,
+                                             args,
+                                             args_descriptor);
+    }
   }
   CheckResultError(result);
   arguments.SetReturn(result);
 }
 
 
+static bool CanOptimizeFunction(const Function& function, Isolate* isolate) {
+  const intptr_t kLowInvocationCount = -100000000;
+  if (isolate->debugger()->HasBreakpoint(function)) {
+    // We cannot set breakpoints in optimized code, so do not optimize
+    // the function.
+    function.set_usage_counter(0);
+    return false;
+  }
+  if (function.deoptimization_counter() >=
+      FLAG_deoptimization_counter_threshold) {
+    if (FLAG_trace_failed_optimization_attempts) {
+      OS::PrintErr("Too Many Deoptimizations: %s\n",
+          function.ToFullyQualifiedCString());
+    }
+    // TODO(srdjan): Investigate excessive deoptimization.
+    function.set_usage_counter(kLowInvocationCount);
+    return false;
+  }
+  if ((FLAG_optimization_filter != NULL) &&
+      (strstr(function.ToFullyQualifiedCString(),
+              FLAG_optimization_filter) == NULL)) {
+    function.set_usage_counter(kLowInvocationCount);
+    return false;
+  }
+  if (!function.is_optimizable()) {
+    if (FLAG_trace_failed_optimization_attempts) {
+      OS::PrintErr("Not Optimizable: %s\n", function.ToFullyQualifiedCString());
+    }
+    // TODO(5442338): Abort as this should not happen.
+    function.set_usage_counter(kLowInvocationCount);
+    return false;
+  }
+  return true;
+}
+
+
 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) {
   ASSERT(arguments.ArgCount() ==
          kStackOverflowRuntimeEntry.argument_count());
@@ -1278,13 +1378,14 @@
     StackFrame* frame = iterator.NextFrame();
     const Function& function = Function::Handle(frame->LookupDartFunction());
     ASSERT(!function.IsNull());
-    if (!function.is_optimizable()) return;
+    if (!CanOptimizeFunction(function, isolate)) return;
     intptr_t osr_id =
         Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc());
     if (FLAG_trace_osr) {
-      OS::Print("Attempting OSR for %s at id=%"Pd"\n",
+      OS::Print("Attempting OSR for %s at id=%"Pd", count=%"Pd"\n",
                 function.ToFullyQualifiedCString(),
-                osr_id);
+                osr_id,
+                function.usage_counter());
     }
 
     const Code& original_code = Code::Handle(function.CurrentCode());
@@ -1332,35 +1433,10 @@
 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
   ASSERT(arguments.ArgCount() ==
          kOptimizeInvokedFunctionRuntimeEntry.argument_count());
-  const intptr_t kLowInvocationCount = -100000000;
   const Function& function = Function::CheckedHandle(arguments.ArgAt(0));
   ASSERT(!function.IsNull());
-  if (isolate->debugger()->HasBreakpoint(function)) {
-    // We cannot set breakpoints in optimized code, so do not optimize
-    // the function.
-    function.set_usage_counter(0);
-    arguments.SetReturn(Code::Handle(function.CurrentCode()));
-    return;
-  }
-  if (function.deoptimization_counter() >=
-      FLAG_deoptimization_counter_threshold) {
-    if (FLAG_trace_failed_optimization_attempts) {
-      OS::PrintErr("Too Many Deoptimizations: %s\n",
-          function.ToFullyQualifiedCString());
-    }
-    // TODO(srdjan): Investigate excessive deoptimization.
-    function.set_usage_counter(kLowInvocationCount);
-    arguments.SetReturn(Code::Handle(function.CurrentCode()));
-    return;
-  }
-  if ((FLAG_optimization_filter != NULL) &&
-      (strstr(function.ToFullyQualifiedCString(),
-              FLAG_optimization_filter) == NULL)) {
-    function.set_usage_counter(kLowInvocationCount);
-    arguments.SetReturn(Code::Handle(function.CurrentCode()));
-    return;
-  }
-  if (function.is_optimizable()) {
+
+  if (CanOptimizeFunction(function, isolate)) {
     const Error& error =
         Error::Handle(Compiler::CompileOptimizedFunction(function));
     if (!error.IsNull()) {
@@ -1370,12 +1446,6 @@
     ASSERT(!optimized_code.IsNull());
     // Reset usage counter for reoptimization.
     function.set_usage_counter(0);
-  } else {
-    if (FLAG_trace_failed_optimization_attempts) {
-      OS::PrintErr("Not Optimizable: %s\n", function.ToFullyQualifiedCString());
-    }
-    // TODO(5442338): Abort as this should not happen.
-    function.set_usage_counter(kLowInvocationCount);
   }
   arguments.SetReturn(Code::Handle(function.CurrentCode()));
 }
@@ -1400,6 +1470,7 @@
   }
   ASSERT(frame->IsDartFrame());
   const Code& caller_code = Code::Handle(frame->LookupDartCode());
+  ASSERT(caller_code.is_optimized());
   const Function& target_function = Function::Handle(
       caller_code.GetStaticCallTargetFunctionAt(frame->pc()));
   const Code& target_code = Code::Handle(target_function.CurrentCode());
diff --git a/runtime/vm/code_generator.h b/runtime/vm/code_generator.h
index 9cfbbf7..95b08cf 100644
--- a/runtime/vm/code_generator.h
+++ b/runtime/vm/code_generator.h
@@ -90,10 +90,8 @@
 const char* DeoptReasonToText(intptr_t deopt_id);
 
 
-RawCode* ResolveCompileInstanceCallTarget(
-    const Instance& receiver,
-    const ICData& ic_data,
-    const Array& arguments_descriptor);
+RawCode* ResolveCompileInstanceCallTarget(const Instance& receiver,
+                                          const ICData& ic_data);
 
 void DeoptimizeAt(const Code& optimized_code, uword pc);
 void DeoptimizeAll();
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index 70d26fd..fea3ba4 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -17,6 +17,7 @@
 class Function;
 class ICData;
 class RawArray;
+class RawFunction;
 class RawICData;
 class String;
 
@@ -53,8 +54,13 @@
   // non-NULL.
   static uword GetInstanceCallAt(uword return_address,
                                  const Code& code,
-                                 ICData* ic_data,
-                                 Array* arguments_descriptor);
+                                 ICData* ic_data);
+
+  // Return target of an unoptimized static call and its ICData object
+  // (calls target via a stub).
+  static RawFunction* GetUnoptimizedStaticCallAt(uword return_address,
+                                                 const Code& code,
+                                                 ICData* ic_data);
 
   // Return the arguments descriptor array of the closure call
   // before the given return address.
diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc
index 0dbb42c..105d3a1 100644
--- a/runtime/vm/code_patcher_arm.cc
+++ b/runtime/vm/code_patcher_arm.cc
@@ -16,7 +16,7 @@
                                            const Code& code) {
   ASSERT(code.ContainsInstructionAt(return_address));
   CallPattern call(return_address, code);
-  return call.ArgumentsDescriptor();
+  return call.ClosureArgumentsDescriptor();
 }
 
 
@@ -55,16 +55,12 @@
 
 uword CodePatcher::GetInstanceCallAt(uword return_address,
                                      const Code& code,
-                                     ICData* ic_data,
-                                     Array* arguments_descriptor) {
+                                     ICData* ic_data) {
   ASSERT(code.ContainsInstructionAt(return_address));
   CallPattern call(return_address, code);
   if (ic_data != NULL) {
     *ic_data = call.IcData();
   }
-  if (arguments_descriptor != NULL) {
-    *arguments_descriptor = call.ArgumentsDescriptor();
-  }
   return call.TargetAddress();
 }
 
@@ -75,6 +71,19 @@
   return 0;
 }
 
+
+RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(
+    uword return_address, const Code& code, ICData* ic_data_result) {
+  ASSERT(code.ContainsInstructionAt(return_address));
+  CallPattern static_call(return_address, code);
+  ICData& ic_data = ICData::Handle();
+  ic_data ^= static_call.IcData();
+  if (ic_data_result != NULL) {
+    *ic_data_result = ic_data.raw();
+  }
+  return ic_data.GetTargetAt(0);
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM
diff --git a/runtime/vm/code_patcher_arm_test.cc b/runtime/vm/code_patcher_arm_test.cc
index 6fbd1a3..a9bfc71 100644
--- a/runtime/vm/code_patcher_arm_test.cc
+++ b/runtime/vm/code_patcher_arm_test.cc
@@ -18,30 +18,6 @@
 
 namespace dart {
 
-CODEGEN_TEST_GENERATE(NativePatchStaticCall, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  const String& native_name =
-      String::ZoneHandle(Symbols::New("TestStaticCallPatching"));
-  NativeFunction native_function =
-      reinterpret_cast<NativeFunction>(TestStaticCallPatching);
-  test->function().set_is_native(true);
-  node_seq->Add(new ReturnNode(Scanner::kDummyTokenIndex,
-                               new NativeBodyNode(Scanner::kDummyTokenIndex,
-                                                  test->function(),
-                                                  native_name,
-                                                  native_function)));
-}
-
-CODEGEN_TEST2_GENERATE(PatchStaticCall, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(Scanner::kDummyTokenIndex);
-  node_seq->Add(new ReturnNode(Scanner::kDummyTokenIndex,
-                               new StaticCallNode(Scanner::kDummyTokenIndex,
-                                                  function, arguments)));
-}
-
-CODEGEN_TEST2_RUN(PatchStaticCall, NativePatchStaticCall, Instance::null());
-
 #define __ assembler->
 
 ASSEMBLER_TEST_GENERATE(IcDataAccess, assembler) {
@@ -49,19 +25,20 @@
   const Script& script = Script::Handle();
   const Class& owner_class =
       Class::Handle(Class::New(class_name, script, Scanner::kDummyTokenIndex));
-  const String& function_name =
-      String::ZoneHandle(Symbols::New("callerFunction"));
-  const Function& function = Function::ZoneHandle(
+  const String& function_name = String::Handle(Symbols::New("callerFunction"));
+  const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
                     true, false, false, false, owner_class, 0));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
-  const ICData& ic_data =
-      ICData::ZoneHandle(ICData::New(function, target_name, 15, 1));
-  const Array& arg_descriptor =
-      Array::ZoneHandle(ArgumentsDescriptor::New(1, Array::Handle()));
+  const Array& args_descriptor =
+      Array::Handle(ArgumentsDescriptor::New(1, Object::null_array()));
+  const ICData& ic_data = ICData::ZoneHandle(ICData::New(function,
+                                                         target_name,
+                                                         args_descriptor,
+                                                         15,
+                                                         1));
 
-  __ LoadObject(R4, arg_descriptor);
   __ LoadObject(R5, ic_data);
   ExternalLabel target_label(
       "InlineCache", StubCode::OneArgCheckInlineCacheEntryPoint());
@@ -74,7 +51,7 @@
   uword return_address =
       test->entry() + test->code().Size() - Instr::kInstrSize;
   ICData& ic_data = ICData::Handle();
-  CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data, NULL);
+  CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data);
   EXPECT_STREQ("targetFunction",
       String::Handle(ic_data.target_name()).ToCString());
   EXPECT_EQ(1, ic_data.num_args_tested());
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index 45ddb0b..d68c938 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -15,14 +15,13 @@
 
 namespace dart {
 
-// The pattern of a Dart instance call is:
-//  1: mov ECX, immediate 1
-//  2: mov EDX, immediate 2
-//  3: call target_address
-//  <- return_address
-class DartCallPattern : public ValueObject {
+// The expected pattern of a Dart unoptimized call (static and instance):
+//  mov ECX, ic-data
+//  call target_address (stub)
+//  <- return address
+class UnoptimizedCall : public ValueObject {
  public:
-  explicit DartCallPattern(uword return_address)
+  explicit UnoptimizedCall(uword return_address)
       : start_(return_address - (kNumInstructions * kInstructionSize)) {
     ASSERT(IsValid(return_address));
     ASSERT(kInstructionSize == Assembler::kCallExternalLabelSize);
@@ -33,8 +32,7 @@
         reinterpret_cast<uint8_t*>(
             return_address - (kNumInstructions * kInstructionSize));
     return (code_bytes[0] == 0xB9) &&
-           (code_bytes[kInstructionSize] == 0xBA) &&
-           (code_bytes[2 * kInstructionSize] == 0xE8);
+           (code_bytes[1 * kInstructionSize] == 0xE8);
   }
 
   uword target() const {
@@ -49,15 +47,11 @@
     CPU::FlushICache(call_address(), kInstructionSize);
   }
 
-  RawObject* immediate_one() const {
+  RawObject* ic_data() const {
     return *reinterpret_cast<RawObject**>(start_ + 1);
   }
 
-  RawObject* immediate_two() const {
-    return *reinterpret_cast<RawObject**>(start_ + kInstructionSize + 1);
-  }
-
-  static const int kNumInstructions = 3;
+  static const int kNumInstructions = 2;
   static const int kInstructionSize = 5;  // All instructions have same length.
 
  private:
@@ -66,32 +60,46 @@
   }
 
   uword call_address() const {
-    return start_ + 2 * kInstructionSize;
+    return start_ + 1 * kInstructionSize;
   }
 
   uword start_;
-  DISALLOW_IMPLICIT_CONSTRUCTORS(DartCallPattern);
+  DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall);
 };
 
 
-// The expected pattern of a dart instance call:
-//  mov ECX, ic-data
-//  mov EDX, arguments_descriptor_array
-//  call target_address
-//  <- return address
-class InstanceCall : public DartCallPattern {
+class InstanceCall : public UnoptimizedCall {
  public:
   explicit InstanceCall(uword return_address)
-      : DartCallPattern(return_address) {}
-
-  RawObject* ic_data() const { return immediate_one(); }
-  RawObject* arguments_descriptor() const { return immediate_two(); }
+      : UnoptimizedCall(return_address) {
+#if defined(DEBUG)
+    ICData& test_ic_data = ICData::Handle();
+    test_ic_data ^= ic_data();
+    ASSERT(test_ic_data.num_args_tested() > 0);
+#endif  // DEBUG
+  }
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall);
 };
 
 
+class UnoptimizedStaticCall : public UnoptimizedCall {
+ public:
+  explicit UnoptimizedStaticCall(uword return_address)
+      : UnoptimizedCall(return_address) {
+#if defined(DEBUG)
+    ICData& test_ic_data = ICData::Handle();
+    test_ic_data ^= ic_data();
+    ASSERT(test_ic_data.num_args_tested() == 0);
+#endif  // DEBUG
+  }
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedStaticCall);
+};
+
+
 // The expected pattern of a dart static call:
 //  mov EDX, arguments_descriptor_array (optional in polymorphic calls)
 //  call target_address
@@ -223,24 +231,32 @@
 }
 
 
-uword CodePatcher::GetInstanceCallAt(uword return_address,
-                                     const Code& code,
-                                     ICData* ic_data,
-                                     Array* arguments_descriptor) {
+uword CodePatcher::GetInstanceCallAt(
+    uword return_address, const Code& code, ICData* ic_data) {
   ASSERT(code.ContainsInstructionAt(return_address));
   InstanceCall call(return_address);
   if (ic_data != NULL) {
     *ic_data ^= call.ic_data();
   }
-  if (arguments_descriptor != NULL) {
-    *arguments_descriptor ^= call.arguments_descriptor();
-  }
   return call.target();
 }
 
 
+RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(
+    uword return_address, const Code& code, ICData* ic_data_result) {
+  ASSERT(code.ContainsInstructionAt(return_address));
+  UnoptimizedStaticCall static_call(return_address);
+  ICData& ic_data = ICData::Handle();
+  ic_data ^= static_call.ic_data();
+  if (ic_data_result != NULL) {
+    *ic_data_result = ic_data.raw();
+  }
+  return ic_data.GetTargetAt(0);
+}
+
+
 intptr_t CodePatcher::InstanceCallSizeInBytes() {
-  return DartCallPattern::kNumInstructions * DartCallPattern::kInstructionSize;
+  return InstanceCall::kNumInstructions * InstanceCall::kInstructionSize;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/code_patcher_ia32_test.cc b/runtime/vm/code_patcher_ia32_test.cc
index 2bb6601..bb893d4 100644
--- a/runtime/vm/code_patcher_ia32_test.cc
+++ b/runtime/vm/code_patcher_ia32_test.cc
@@ -18,30 +18,6 @@
 
 namespace dart {
 
-CODEGEN_TEST_GENERATE(NativePatchStaticCall, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  const String& native_name =
-      String::ZoneHandle(Symbols::New("TestStaticCallPatching"));
-  NativeFunction native_function =
-      reinterpret_cast<NativeFunction>(TestStaticCallPatching);
-  test->function().set_is_native(true);
-  node_seq->Add(new ReturnNode(Scanner::kDummyTokenIndex,
-                               new NativeBodyNode(Scanner::kDummyTokenIndex,
-                                                  test->function(),
-                                                  native_name,
-                                                  native_function)));
-}
-
-CODEGEN_TEST2_GENERATE(PatchStaticCall, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(Scanner::kDummyTokenIndex);
-  node_seq->Add(new ReturnNode(Scanner::kDummyTokenIndex,
-                               new StaticCallNode(Scanner::kDummyTokenIndex,
-                                                  function, arguments)));
-}
-
-CODEGEN_TEST2_RUN(PatchStaticCall, NativePatchStaticCall, Instance::null());
-
 #define __ assembler->
 
 ASSEMBLER_TEST_GENERATE(IcDataAccess, assembler) {
@@ -49,20 +25,21 @@
   const Script& script = Script::Handle();
   const Class& owner_class =
       Class::Handle(Class::New(class_name, script, Scanner::kDummyTokenIndex));
-  const String& function_name =
-      String::ZoneHandle(Symbols::New("callerFunction"));
-  const Function& function = Function::ZoneHandle(
+  const String& function_name = String::Handle(Symbols::New("callerFunction"));
+  const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
                     true, false, false, false, owner_class, 0));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
-  const ICData& ic_data =
-      ICData::ZoneHandle(ICData::New(function, target_name, 15, 1));
-  const Array& arg_descriptor =
-      Array::ZoneHandle(ArgumentsDescriptor::New(1, Array::Handle()));
+  const Array& args_descriptor =
+      Array::Handle(ArgumentsDescriptor::New(1, Object::null_array()));
+  const ICData& ic_data = ICData::ZoneHandle(ICData::New(function,
+                                                         target_name,
+                                                         args_descriptor,
+                                                         15,
+                                                         1));
 
   __ LoadObject(ECX, ic_data);
-  __ LoadObject(EDX, arg_descriptor);
   ExternalLabel target_label(
       "InlineCache", StubCode::OneArgCheckInlineCacheEntryPoint());
   __ call(&target_label);
@@ -73,7 +50,7 @@
 ASSEMBLER_TEST_RUN(IcDataAccess, test) {
   uword return_address = test->entry() + CodePatcher::InstanceCallSizeInBytes();
   ICData& ic_data = ICData::Handle();
-  CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data, NULL);
+  CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data);
   EXPECT_STREQ("targetFunction",
       String::Handle(ic_data.target_name()).ToCString());
   EXPECT_EQ(1, ic_data.num_args_tested());
diff --git a/runtime/vm/code_patcher_mips.cc b/runtime/vm/code_patcher_mips.cc
index 5cd9108..f25b460 100644
--- a/runtime/vm/code_patcher_mips.cc
+++ b/runtime/vm/code_patcher_mips.cc
@@ -16,7 +16,7 @@
                                            const Code& code) {
   ASSERT(code.ContainsInstructionAt(return_address));
   CallPattern call(return_address, code);
-  return call.ArgumentsDescriptor();
+  return call.ClosureArgumentsDescriptor();
 }
 
 
@@ -55,16 +55,12 @@
 
 uword CodePatcher::GetInstanceCallAt(uword return_address,
                                      const Code& code,
-                                     ICData* ic_data,
-                                     Array* arguments_descriptor) {
+                                     ICData* ic_data) {
   ASSERT(code.ContainsInstructionAt(return_address));
   CallPattern call(return_address, code);
   if (ic_data != NULL) {
     *ic_data = call.IcData();
   }
-  if (arguments_descriptor != NULL) {
-    *arguments_descriptor = call.ArgumentsDescriptor();
-  }
   return call.TargetAddress();
 }
 
@@ -75,6 +71,19 @@
   return 0;
 }
 
+
+RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(
+    uword return_address, const Code& code, ICData* ic_data_result) {
+  ASSERT(code.ContainsInstructionAt(return_address));
+  CallPattern static_call(return_address, code);
+  ICData& ic_data = ICData::Handle();
+  ic_data ^= static_call.IcData();
+  if (ic_data_result != NULL) {
+    *ic_data_result = ic_data.raw();
+  }
+  return ic_data.GetTargetAt(0);
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/code_patcher_mips_test.cc b/runtime/vm/code_patcher_mips_test.cc
index 9d0a681..c5b51b5 100644
--- a/runtime/vm/code_patcher_mips_test.cc
+++ b/runtime/vm/code_patcher_mips_test.cc
@@ -18,30 +18,6 @@
 
 namespace dart {
 
-CODEGEN_TEST_GENERATE(NativePatchStaticCall, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  const String& native_name =
-      String::ZoneHandle(Symbols::New("TestStaticCallPatching"));
-  NativeFunction native_function =
-      reinterpret_cast<NativeFunction>(TestStaticCallPatching);
-  test->function().set_is_native(true);
-  node_seq->Add(new ReturnNode(Scanner::kDummyTokenIndex,
-                               new NativeBodyNode(Scanner::kDummyTokenIndex,
-                                                  test->function(),
-                                                  native_name,
-                                                  native_function)));
-}
-
-CODEGEN_TEST2_GENERATE(PatchStaticCall, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(Scanner::kDummyTokenIndex);
-  node_seq->Add(new ReturnNode(Scanner::kDummyTokenIndex,
-                               new StaticCallNode(Scanner::kDummyTokenIndex,
-                                                  function, arguments)));
-}
-
-CODEGEN_TEST2_RUN(PatchStaticCall, NativePatchStaticCall, Instance::null());
-
 #define __ assembler->
 
 ASSEMBLER_TEST_GENERATE(IcDataAccess, assembler) {
@@ -49,19 +25,20 @@
   const Script& script = Script::Handle();
   const Class& owner_class =
       Class::Handle(Class::New(class_name, script, Scanner::kDummyTokenIndex));
-  const String& function_name =
-      String::ZoneHandle(Symbols::New("callerFunction"));
-  const Function& function = Function::ZoneHandle(
+  const String& function_name = String::Handle(Symbols::New("callerFunction"));
+  const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
                     true, false, false, false, owner_class, 0));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
-  const ICData& ic_data =
-      ICData::ZoneHandle(ICData::New(function, target_name, 15, 1));
-  const Array& arg_descriptor =
-      Array::ZoneHandle(ArgumentsDescriptor::New(1, Array::Handle()));
+  const Array& args_descriptor =
+      Array::Handle(ArgumentsDescriptor::New(1, Object::null_array()));
+  const ICData& ic_data = ICData::ZoneHandle(ICData::New(function,
+                                                         target_name,
+                                                         args_descriptor,
+                                                         15,
+                                                         1));
 
-  __ LoadObject(S4, arg_descriptor);
   __ LoadObject(S5, ic_data);
   ExternalLabel target_label(
       "InlineCache", StubCode::OneArgCheckInlineCacheEntryPoint());
@@ -74,7 +51,7 @@
   uword return_address =
       test->entry() + test->code().Size() - 2 * Instr::kInstrSize;
   ICData& ic_data = ICData::Handle();
-  CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data, NULL);
+  CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data);
   EXPECT_STREQ("targetFunction",
       String::Handle(ic_data.target_name()).ToCString());
   EXPECT_EQ(1, ic_data.num_args_tested());
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index 82652d0..ec9e56f 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -15,76 +15,82 @@
 
 namespace dart {
 
-// The pattern of a Dart instance call is:
-//  00: 48 bb imm64  mov RBX, immediate 1
-//  10: 49 ba imm64  mov R10, immediate 2
-//  20: 49 bb imm64  mov R11, target_address
-//  30: 41 ff d3     call R11
-//  33: <- return_address
-class DartCallPattern : public ValueObject {
+// The expected pattern of a Dart unoptimized call (static and instance):
+//  00: 48 bb imm64  mov RBX, ic-data
+//  10: 49 bb imm64  mov R11, target_address
+//  20: 41 ff d3   call R11
+//  23 <- return address
+class UnoptimizedCall : public ValueObject {
  public:
-  explicit DartCallPattern(uword return_address)
+  explicit UnoptimizedCall(uword return_address)
       : start_(return_address - kCallPatternSize) {
     ASSERT(IsValid(return_address));
-    ASSERT((kCallPatternSize - 20) == Assembler::kCallExternalLabelSize);
+    ASSERT((kCallPatternSize - 10) == Assembler::kCallExternalLabelSize);
   }
 
-  static const int kCallPatternSize = 33;
+  static const int kCallPatternSize = 23;
 
   static bool IsValid(uword return_address) {
     uint8_t* code_bytes =
         reinterpret_cast<uint8_t*>(return_address - kCallPatternSize);
     return (code_bytes[00] == 0x48) && (code_bytes[01] == 0xBB) &&
-           (code_bytes[10] == 0x49) && (code_bytes[11] == 0xBA) &&
-           (code_bytes[20] == 0x49) && (code_bytes[21] == 0xBB) &&
-           (code_bytes[30] == 0x41) && (code_bytes[31] == 0xFF) &&
-           (code_bytes[32] == 0xD3);
+           (code_bytes[10] == 0x49) && (code_bytes[11] == 0xBB) &&
+           (code_bytes[20] == 0x41) && (code_bytes[21] == 0xFF) &&
+           (code_bytes[22] == 0xD3);
   }
 
-  uword target() const {
-    return *reinterpret_cast<uword*>(start_ + 20 + 2);
-  }
-
-  void set_target(uword target) const {
-    uword* target_addr = reinterpret_cast<uword*>(start_ + 20 + 2);
-    *target_addr = target;
-    CPU::FlushICache(start_ + 20, 2 + 8);
-  }
-
-  RawObject* immediate_one() const {
+  RawObject* ic_data() const {
     return *reinterpret_cast<RawObject**>(start_ + 0 + 2);
   }
 
-  RawObject* immediate_two() const {
-    return *reinterpret_cast<RawObject**>(start_ + 10 + 2);
+  uword target() const {
+    return *reinterpret_cast<uword*>(start_ + 10 + 2);
+  }
+
+  void set_target(uword target) const {
+    uword* target_addr = reinterpret_cast<uword*>(start_ + 10 + 2);
+    *target_addr = target;
+    CPU::FlushICache(start_ + 10, 2 + 8);
   }
 
  private:
   uword start_;
-  DISALLOW_IMPLICIT_CONSTRUCTORS(DartCallPattern);
+  DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall);
 };
 
 
-// A Dart instance call passes the ic-data in RBX.
-// The expected pattern of a dart instance call:
-//  mov RBX, ic-data
-//  mov R10, arguments_descriptor_array
-//  mov R11, target_address
-//  call R11
-//  <- return address
-class InstanceCall : public DartCallPattern {
+class InstanceCall : public UnoptimizedCall {
  public:
   explicit InstanceCall(uword return_address)
-      : DartCallPattern(return_address) {}
-
-  RawObject* ic_data() const { return immediate_one(); }
-  RawObject* arguments_descriptor() const { return immediate_two(); }
+      : UnoptimizedCall(return_address) {
+#if defined(DEBUG)
+    ICData& test_ic_data = ICData::Handle();
+    test_ic_data ^= ic_data();
+    ASSERT(test_ic_data.num_args_tested() > 0);
+#endif  // DEBUG
+  }
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall);
 };
 
 
+class UnoptimizedStaticCall : public UnoptimizedCall {
+ public:
+  explicit UnoptimizedStaticCall(uword return_address)
+      : UnoptimizedCall(return_address) {
+#if defined(DEBUG)
+    ICData& test_ic_data = ICData::Handle();
+    test_ic_data ^= ic_data();
+    ASSERT(test_ic_data.num_args_tested() == 0);
+#endif  // DEBUG
+  }
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedStaticCall);
+};
+
+
 // The expected pattern of a dart static call:
 //  mov R10, arguments_descriptor_array (10 bytes) (optional in polym. calls)
 //  mov R11, target_address (10 bytes)
@@ -193,22 +199,18 @@
 
 uword CodePatcher::GetInstanceCallAt(uword return_address,
                                      const Code& code,
-                                     ICData* ic_data,
-                                     Array* arguments_descriptor) {
+                                     ICData* ic_data) {
   ASSERT(code.ContainsInstructionAt(return_address));
   InstanceCall call(return_address);
   if (ic_data != NULL) {
     *ic_data ^= call.ic_data();
   }
-  if (arguments_descriptor != NULL) {
-    *arguments_descriptor ^= call.arguments_descriptor();
-  }
   return call.target();
 }
 
 
 intptr_t CodePatcher::InstanceCallSizeInBytes() {
-  return DartCallPattern::kCallPatternSize;
+  return InstanceCall::kCallPatternSize;
 }
 
 
@@ -222,6 +224,18 @@
 }
 
 
+RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(
+    uword return_address, const Code& code, ICData* ic_data_result) {
+  ASSERT(code.ContainsInstructionAt(return_address));
+  UnoptimizedStaticCall static_call(return_address);
+  ICData& ic_data = ICData::Handle();
+  ic_data ^= static_call.ic_data();
+  if (ic_data_result != NULL) {
+    *ic_data_result = ic_data.raw();
+  }
+  return ic_data.GetTargetAt(0);
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_X64
diff --git a/runtime/vm/code_patcher_x64_test.cc b/runtime/vm/code_patcher_x64_test.cc
index 61807b3..202c27a 100644
--- a/runtime/vm/code_patcher_x64_test.cc
+++ b/runtime/vm/code_patcher_x64_test.cc
@@ -18,30 +18,6 @@
 
 namespace dart {
 
-CODEGEN_TEST_GENERATE(NativePatchStaticCall, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  const String& native_name =
-      String::ZoneHandle(Symbols::New("TestStaticCallPatching"));
-  NativeFunction native_function =
-      reinterpret_cast<NativeFunction>(TestStaticCallPatching);
-  test->function().set_is_native(true);
-  node_seq->Add(new ReturnNode(Scanner::kDummyTokenIndex,
-                               new NativeBodyNode(Scanner::kDummyTokenIndex,
-                                                  test->function(),
-                                                  native_name,
-                                                  native_function)));
-}
-
-CODEGEN_TEST2_GENERATE(PatchStaticCall, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(Scanner::kDummyTokenIndex);
-  node_seq->Add(new ReturnNode(Scanner::kDummyTokenIndex,
-                               new StaticCallNode(Scanner::kDummyTokenIndex,
-                                                  function, arguments)));
-}
-
-CODEGEN_TEST2_RUN(PatchStaticCall, NativePatchStaticCall, Instance::null());
-
 #define __ assembler->
 
 ASSEMBLER_TEST_GENERATE(IcDataAccess, assembler) {
@@ -49,20 +25,21 @@
   const Script& script = Script::Handle();
   const Class& owner_class =
       Class::Handle(Class::New(class_name, script, Scanner::kDummyTokenIndex));
-  const String& function_name =
-      String::ZoneHandle(Symbols::New("callerFunction"));
-  const Function& function = Function::ZoneHandle(
+  const String& function_name = String::Handle(Symbols::New("callerFunction"));
+  const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
                     true, false, false, false, owner_class, 0));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
-  const ICData& ic_data =
-      ICData::ZoneHandle(ICData::New(function, target_name, 15, 1));
-  const Array& arg_descriptor =
-      Array::ZoneHandle(ArgumentsDescriptor::New(1, Array::Handle()));
+  const Array& args_descriptor =
+      Array::Handle(ArgumentsDescriptor::New(1, Object::null_array()));
+  const ICData& ic_data = ICData::ZoneHandle(ICData::New(function,
+                                                         target_name,
+                                                         args_descriptor,
+                                                         15,
+                                                         1));
 
   __ LoadObject(RBX, ic_data);
-  __ LoadObject(R10, arg_descriptor);
   ExternalLabel target_label(
       "InlineCache", StubCode::OneArgCheckInlineCacheEntryPoint());
   __ call(&target_label);
@@ -73,7 +50,7 @@
 ASSEMBLER_TEST_RUN(IcDataAccess, test) {
   uword return_address = test->entry() + CodePatcher::InstanceCallSizeInBytes();
   ICData& ic_data = ICData::Handle();
-  CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data, NULL);
+  CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data);
   EXPECT_STREQ("targetFunction",
       String::Handle(ic_data.target_name()).ToCString());
   EXPECT_EQ(1, ic_data.num_args_tested());
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 0fba07c..2faa434 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -268,14 +268,11 @@
         ASSERT(function.HasCode());
         // Extract type feedback before the graph is built, as the graph
         // builder uses it to attach it to nodes.
-        // Do not use type feedback to optimize a function that was
-        // deoptimized too often.
-        if (function.deoptimization_counter() <
-            FLAG_deoptimization_counter_threshold) {
-          const Code& unoptimized_code =
-              Code::Handle(function.unoptimized_code());
-          ic_data_array = unoptimized_code.ExtractTypeFeedbackArray();
-        }
+        ASSERT(function.deoptimization_counter() <
+               FLAG_deoptimization_counter_threshold);
+        const Code& unoptimized_code =
+            Code::Handle(function.unoptimized_code());
+        ic_data_array = unoptimized_code.ExtractTypeFeedbackArray();
       }
 
       // Build the flow graph.
@@ -863,7 +860,7 @@
     // here.
     ParsedFunction* parsed_function = new ParsedFunction(func);
     parsed_function->SetNodeSequence(fragment);
-    parsed_function->set_default_parameter_values(Array::ZoneHandle());
+    parsed_function->set_default_parameter_values(Object::null_array());
     parsed_function->EnsureExpressionTemp();
     fragment->scope()->AddVariable(parsed_function->expression_temp_var());
     parsed_function->AllocateVariables();
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index b1f910a..bb16ccd 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -135,23 +135,22 @@
 // convert to the single precision registers when needed in the mips-specific
 // code.
 enum DRegister {
-  D0  =  0,
-  D1  =  1,
-  D2  =  2,
-  D3  =  3,
-  D4  =  4,
-  D5  =  5,
-  D6  =  6,
-  D7  =  7,
-  D8  =  8,
-  D9  =  9,
-  D10 = 10,
-  D11 = 11,
-  D12 = 12,
-  D13 = 13,
-  D14 = 14,
-  D15 = 15,
-  D16 = 16,
+  D0  =  0,  // Function return value 1.
+  D1  =  1,  // Function return value 2.
+  D2  =  2,  // Not preserved.
+  D3  =  3,  // Not preserved.
+  D4  =  4,  // Not preserved.
+  D5  =  5,  // Not preserved.
+  D6  =  6,  // Argument 1.
+  D7  =  7,  // Argument 2.
+  D8  =  8,  // Not preserved.
+  D9  =  9,  // Not preserved.
+  D10 = 10,  // Preserved.
+  D11 = 11,  // Preserved.
+  D12 = 12,  // Preserved.
+  D13 = 13,  // Preserved.
+  D14 = 14,  // Preserved.
+  D15 = 15,  // Preserved.
   kNumberOfDRegisters = 16,
   kNoDRegister = -1,
 };
@@ -409,6 +408,7 @@
   COP1_DIV = 0x03,
   COP1_SQRT = 0x04,
   COP1_MOV = 0x06,
+  COP1_CVT_S = 0x20,
   COP1_CVT_D = 0x21,
   COP1_CVT_W = 0x24,
   COP1_C_F = 0x30,
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index b68c88a..300e5b3 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -193,6 +193,11 @@
   Object::VerifyBuiltinVtables();
 
   StubCode::Init(isolate);
+  if (snapshot_buffer == NULL) {
+    if (!isolate->object_store()->PreallocateObjects()) {
+      return isolate->object_store()->sticky_error();
+    }
+  }
   isolate->megamorphic_cache_table()->InitMissHandler();
 
   isolate->heap()->EnableGrowthControl();
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 176407c..99e6cca 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -133,8 +133,11 @@
 
 
 Dart_Handle Api::CheckIsolateState(Isolate* isolate) {
-  if (ClassFinalizer::FinalizePendingClasses() &&
-      isolate->object_store()->PreallocateObjects()) {
+  if (!isolate->AllowClassFinalization()) {
+    // Class finalization is blocked for the isolate. Do nothing.
+    return Api::Success();
+  }
+  if (ClassFinalizer::FinalizePendingClasses()) {
     return Api::Success();
   }
   ASSERT(isolate->object_store()->sticky_error() != Object::null());
@@ -1136,16 +1139,25 @@
 // Do we also need a real Dart_IsInstanceOf, which should take an instance
 // rather than an object and a type rather than a class?
 DART_EXPORT Dart_Handle Dart_ObjectIsType(Dart_Handle object,
-                                          Dart_Handle clazz,
+                                          Dart_Handle type,
                                           bool* value) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
 
-  const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
-  if (cls.IsNull()) {
-    RETURN_TYPE_ERROR(isolate, clazz, Class);
+  Type& type_obj = Type::Handle();
+  Object& obj = Object::Handle(isolate, Api::UnwrapHandle(type));
+  if (obj.IsNull()) {
+    RETURN_NULL_ERROR(type);
   }
-  const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object));
+  if (obj.IsType()) {
+    type_obj ^= obj.raw();
+  } else {
+    if (!obj.IsClass()) {
+      RETURN_TYPE_ERROR(isolate, type, Type);
+    }
+    type_obj ^= Type::NewNonParameterizedType(Class::Cast(obj));
+  }
+  obj = Api::UnwrapHandle(object);
   if (obj.IsError()) {
     return object;
   } else if (!obj.IsNull() && !obj.IsInstance()) {
@@ -1160,10 +1172,8 @@
   }
   if (obj.IsInstance()) {
     CHECK_CALLBACK_STATE(isolate);
-    const Type& type = Type::Handle(isolate,
-                                    Type::NewNonParameterizedType(cls));
     Error& malformed_type_error = Error::Handle(isolate);
-    *value = Instance::Cast(obj).IsInstanceOf(type,
+    *value = Instance::Cast(obj).IsInstanceOf(type_obj,
                                               TypeArguments::Handle(isolate),
                                               &malformed_type_error);
     ASSERT(malformed_type_error.IsNull());  // Type was created from a class.
@@ -1234,6 +1244,11 @@
 }
 
 
+DART_EXPORT bool Dart_IsType(Dart_Handle handle) {
+  return Api::ClassId(handle) == kTypeCid;
+}
+
+
 DART_EXPORT bool Dart_IsClass(Dart_Handle handle) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
@@ -1242,17 +1257,6 @@
 }
 
 
-DART_EXPORT bool Dart_IsAbstractClass(Dart_Handle handle) {
-  Isolate* isolate = Isolate::Current();
-  DARTSCOPE(isolate);
-  const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle));
-  if (obj.IsClass()) {
-    return Class::Cast(obj).is_abstract();
-  }
-  return false;
-}
-
-
 DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) {
   return Api::ClassId(handle) == kFunctionCid;
 }
@@ -1280,7 +1284,21 @@
 
 // --- Instances ----
 
-// TODO(turnidge): Technically, null has a class.  Should we allow it?
+DART_EXPORT Dart_Handle Dart_InstanceGetType(Dart_Handle instance) {
+  Isolate* isolate = Isolate::Current();
+  DARTSCOPE(isolate);
+  const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(instance));
+  if (obj.IsNull()) {
+    return Api::NewHandle(isolate, isolate->object_store()->null_type());
+  }
+  if (!obj.IsInstance()) {
+    RETURN_TYPE_ERROR(isolate, instance, Instance);
+  }
+  const Type& type = Type::Handle(Instance::Cast(obj).GetType());
+  return Api::NewHandle(isolate, type.Canonicalize());
+}
+
+// TODO(asiva): Deprecate this method.
 DART_EXPORT Dart_Handle Dart_InstanceGetClass(Dart_Handle instance) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
@@ -2707,7 +2725,7 @@
 }
 
 
-DART_EXPORT Dart_Handle Dart_New(Dart_Handle clazz,
+DART_EXPORT Dart_Handle Dart_New(Dart_Handle type,
                                  Dart_Handle constructor_name,
                                  int number_of_arguments,
                                  Dart_Handle* arguments) {
@@ -2723,10 +2741,20 @@
   }
 
   // Get the class to instantiate.
-  Class& cls =
-      Class::Handle(isolate, Api::UnwrapClassHandle(isolate, clazz).raw());
-  if (cls.IsNull()) {
-    RETURN_TYPE_ERROR(isolate, clazz, Class);
+  result = Api::UnwrapHandle(type);
+  if (result.IsNull()) {
+    RETURN_TYPE_ERROR(isolate, type, Type);
+  }
+  Class& cls = Class::Handle(isolate);
+  if (result.IsType()) {
+    cls = Type::Cast(result).type_class();
+  } else if (result.IsClass()) {
+    // For backwards compatibility we allow class objects to be passed in
+    // for now. This needs to be removed once all code that uses class
+    // objects to invoke Dart_New is removed.
+    cls ^= result.raw();
+  } else {
+    RETURN_TYPE_ERROR(isolate, type, Type);
   }
 
   String& base_constructor_name = String::Handle();
@@ -2734,12 +2762,11 @@
 
   // And get the name of the constructor to invoke.
   String& dot_name = String::Handle(isolate);
-  const Object& name_obj =
-      Object::Handle(isolate, Api::UnwrapHandle(constructor_name));
-  if (name_obj.IsNull()) {
+  result = Api::UnwrapHandle(constructor_name);
+  if (result.IsNull()) {
     dot_name = Symbols::Dot().raw();
-  } else if (name_obj.IsString()) {
-    dot_name = String::Concat(Symbols::Dot(), String::Cast(name_obj));
+  } else if (result.IsString()) {
+    dot_name = String::Concat(Symbols::Dot(), String::Cast(result));
   } else {
     RETURN_TYPE_ERROR(isolate, constructor_name, String);
   }
@@ -2818,6 +2845,33 @@
 }
 
 
+DART_EXPORT Dart_Handle Dart_Allocate(Dart_Handle type) {
+  Isolate* isolate = Isolate::Current();
+  DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
+  const Object& result = Object::Handle(isolate, Api::UnwrapHandle(type));
+
+  // Get the class to instantiate.
+  if (result.IsNull()) {
+    RETURN_TYPE_ERROR(isolate, type, Type);
+  }
+  Class& cls = Class::Handle(isolate);
+  if (result.IsType()) {
+    cls = Type::Cast(result).type_class();
+  } else if (result.IsClass()) {
+    // For backwards compatibility we allow class objects to be passed in
+    // for now. This needs to be removed once all code that uses class
+    // objects to invoke Dart_New is removed.
+    cls ^= result.raw();
+  } else {
+    RETURN_TYPE_ERROR(isolate, type, Type);
+  }
+
+  // Allocate an object for the given class.
+  return Api::NewHandle(isolate, Instance::New(cls));
+}
+
+
 DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target,
                                     Dart_Handle name,
                                     int number_of_arguments,
@@ -2841,7 +2895,8 @@
   }
 
   // Check for malformed arguments in the arguments list.
-  intptr_t num_receiver = (obj.IsNull() || obj.IsInstance()) ? 1 : 0;
+  intptr_t num_receiver =
+      (obj.IsNull() || (obj.IsInstance() && !obj.IsType())) ? 1 : 0;
   const Array& args =
       Array::Handle(isolate, Array::New(number_of_arguments + num_receiver));
   Object& arg = Object::Handle(isolate);
@@ -2859,7 +2914,39 @@
     args.SetAt((i + num_receiver), arg);
   }
 
-  if (obj.IsNull() || obj.IsInstance()) {
+  if (obj.IsType() || obj.IsClass()) {
+    // Finalize all classes.
+    Dart_Handle state = Api::CheckIsolateState(isolate);
+    if (::Dart_IsError(state)) {
+      return state;
+    }
+
+    // For backwards compatibility we allow class objects to be passed in
+    // for now. This needs to be removed once all code that uses class
+    // objects to invoke Dart_Invoke is removed.
+    Class& cls = Class::Handle();
+    if (obj.IsType()) {
+      cls = Type::Cast(obj).type_class();
+    } else {
+      cls = Class::Cast(obj).raw();
+    }
+    const Function& function = Function::Handle(
+        isolate,
+        Resolver::ResolveStatic(cls,
+                                function_name,
+                                number_of_arguments,
+                                Object::empty_array(),
+                                Resolver::kIsQualified));
+    if (function.IsNull()) {
+      const String& cls_name = String::Handle(isolate, cls.Name());
+      return Api::NewError("%s: did not find static method '%s.%s'.",
+                           CURRENT_FUNC,
+                           cls_name.ToCString(),
+                           function_name.ToCString());
+    }
+    return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args));
+
+  } else if (obj.IsNull() || obj.IsInstance()) {
     Instance& instance = Instance::Handle(isolate);
     instance ^= obj.raw();
     const Function& function = Function::Handle(
@@ -2880,51 +2967,16 @@
     }
     return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args));
 
-  } else if (obj.IsClass()) {
-    // Finalize all classes.
+  } else if (obj.IsLibrary()) {
+    // Check whether class finalization is needed.
+    const Library& lib = Library::Cast(obj);
+
+    // Finalize all classes if needed.
     Dart_Handle state = Api::CheckIsolateState(isolate);
     if (::Dart_IsError(state)) {
       return state;
     }
 
-    const Class& cls = Class::Cast(obj);
-    const Function& function = Function::Handle(
-        isolate,
-        Resolver::ResolveStatic(cls,
-                                function_name,
-                                number_of_arguments,
-                                Object::empty_array(),
-                                Resolver::kIsQualified));
-    if (function.IsNull()) {
-      const String& cls_name = String::Handle(isolate, cls.Name());
-      return Api::NewError("%s: did not find static method '%s.%s'.",
-                           CURRENT_FUNC,
-                           cls_name.ToCString(),
-                           function_name.ToCString());
-    }
-    return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args));
-
-  } else if (obj.IsLibrary()) {
-    // Check whether class finalization is needed.
-    bool finalize_classes = true;
-    const Library& lib = Library::Cast(obj);
-
-    // When calling functions in the dart:builtin library do not finalize as it
-    // should have been prefinalized.
-    Library& builtin =
-        Library::Handle(isolate, isolate->object_store()->builtin_library());
-    if (builtin.raw() == lib.raw()) {
-      finalize_classes = false;
-    }
-
-    // Finalize all classes if needed.
-    if (finalize_classes) {
-      Dart_Handle state = Api::CheckIsolateState(isolate);
-      if (::Dart_IsError(state)) {
-        return state;
-      }
-    }
-
     Function& function = Function::Handle(isolate);
     function = lib.LookupFunctionAllowPrivate(function_name);
     if (function.IsNull()) {
@@ -2947,7 +2999,7 @@
 
   } else {
     return Api::NewError(
-        "%s expects argument 'target' to be an object, class, or library.",
+        "%s expects argument 'target' to be an object, type, or library.",
         CURRENT_FUNC);
   }
 }
@@ -3014,12 +3066,43 @@
   if (::Dart_IsError(state)) {
     return state;
   }
+
   Field& field = Field::Handle(isolate);
   Function& getter = Function::Handle(isolate);
   const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(container));
   if (obj.IsNull()) {
     return Api::NewError("%s expects argument 'container' to be non-null.",
                          CURRENT_FUNC);
+  } else if (obj.IsType() || obj.IsClass()) {
+    // To access a static field we may need to use the Field or the
+    // getter Function.
+    // For backwards compatibility we allow class objects to be passed in
+    // for now. This needs to be removed once all code that uses class
+    // objects to invoke Dart_GetField is removed.
+    Class& cls = Class::Handle();
+    if (obj.IsType()) {
+      cls = Type::Cast(obj).type_class();
+    } else {
+      cls = Class::Cast(obj).raw();
+    }
+    field = cls.LookupStaticField(field_name);
+    if (field.IsNull() || FieldIsUninitialized(isolate, field)) {
+      const String& getter_name =
+          String::Handle(isolate, Field::GetterName(field_name));
+      getter = cls.LookupStaticFunctionAllowPrivate(getter_name);
+    }
+
+    if (!getter.IsNull()) {
+      // Invoke the getter and return the result.
+      return Api::NewHandle(
+          isolate, DartEntry::InvokeFunction(getter, Object::empty_array()));
+    } else if (!field.IsNull()) {
+      return Api::NewHandle(isolate, field.value());
+    } else {
+      return Api::NewError("%s: did not find static field '%s'.",
+                           CURRENT_FUNC, field_name.ToCString());
+    }
+
   } else if (obj.IsInstance()) {
     // Every instance field has a getter Function.  Try to find the
     // getter in any superclass and use that function to access the
@@ -3051,28 +3134,6 @@
     }
     return Api::NewHandle(isolate, DartEntry::InvokeFunction(getter, args));
 
-  } else if (obj.IsClass()) {
-    // To access a static field we may need to use the Field or the
-    // getter Function.
-    const Class& cls = Class::Cast(obj);
-    field = cls.LookupStaticField(field_name);
-    if (field.IsNull() || FieldIsUninitialized(isolate, field)) {
-      const String& getter_name =
-          String::Handle(isolate, Field::GetterName(field_name));
-      getter = cls.LookupStaticFunctionAllowPrivate(getter_name);
-    }
-
-    if (!getter.IsNull()) {
-      // Invoke the getter and return the result.
-      return Api::NewHandle(
-          isolate, DartEntry::InvokeFunction(getter, Object::empty_array()));
-    } else if (!field.IsNull()) {
-      return Api::NewHandle(isolate, field.value());
-    } else {
-      return Api::NewError("%s: did not find static field '%s'.",
-                           CURRENT_FUNC, field_name.ToCString());
-    }
-
   } else if (obj.IsLibrary()) {
     // To access a top-level we may need to use the Field or the
     // getter Function.  The getter function may either be in the
@@ -3107,7 +3168,7 @@
       return container;
   } else {
     return Api::NewError(
-        "%s expects argument 'container' to be an object, class, or library.",
+        "%s expects argument 'container' to be an object, type, or library.",
         CURRENT_FUNC);
   }
 }
@@ -3144,6 +3205,50 @@
   if (obj.IsNull()) {
     return Api::NewError("%s expects argument 'container' to be non-null.",
                          CURRENT_FUNC);
+  } else if (obj.IsType() || obj.IsClass()) {
+    // To access a static field we may need to use the Field or the
+    // setter Function.
+    // For backwards compatibility we allow class objects to be passed in
+    // for now. This needs to be removed once all code that uses class
+    // objects to invoke Dart_SetField is removed.
+    Class& cls = Class::Handle();
+    if (obj.IsType()) {
+      cls = Type::Cast(obj).type_class();
+    } else {
+      cls = Class::Cast(obj).raw();
+    }
+    field = cls.LookupStaticField(field_name);
+    if (field.IsNull()) {
+      String& setter_name =
+          String::Handle(isolate, Field::SetterName(field_name));
+      setter = cls.LookupStaticFunctionAllowPrivate(setter_name);
+    }
+
+    if (!setter.IsNull()) {
+      // Invoke the setter and return the result.
+      const int kNumArgs = 1;
+      const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
+      args.SetAt(0, value_instance);
+      const Object& result =
+          Object::Handle(isolate, DartEntry::InvokeFunction(setter, args));
+      if (result.IsError()) {
+        return Api::NewHandle(isolate, result.raw());
+      } else {
+        return Api::Success();
+      }
+    } else if (!field.IsNull()) {
+      if (field.is_final()) {
+        return Api::NewError("%s: cannot set final field '%s'.",
+                             CURRENT_FUNC, field_name.ToCString());
+      } else {
+        field.set_value(value_instance);
+        return Api::Success();
+      }
+    } else {
+      return Api::NewError("%s: did not find static field '%s'.",
+                           CURRENT_FUNC, field_name.ToCString());
+    }
+
   } else if (obj.IsInstance()) {
     // Every instance field has a setter Function.  Try to find the
     // setter in any superclass and use that function to access the
@@ -3181,42 +3286,6 @@
     }
     return Api::NewHandle(isolate, DartEntry::InvokeFunction(setter, args));
 
-  } else if (obj.IsClass()) {
-    // To access a static field we may need to use the Field or the
-    // setter Function.
-    const Class& cls = Class::Cast(obj);
-    field = cls.LookupStaticField(field_name);
-    if (field.IsNull()) {
-      String& setter_name =
-          String::Handle(isolate, Field::SetterName(field_name));
-      setter = cls.LookupStaticFunctionAllowPrivate(setter_name);
-    }
-
-    if (!setter.IsNull()) {
-      // Invoke the setter and return the result.
-      const int kNumArgs = 1;
-      const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
-      args.SetAt(0, value_instance);
-      const Object& result =
-          Object::Handle(isolate, DartEntry::InvokeFunction(setter, args));
-      if (result.IsError()) {
-        return Api::NewHandle(isolate, result.raw());
-      } else {
-        return Api::Success();
-      }
-    } else if (!field.IsNull()) {
-      if (field.is_final()) {
-        return Api::NewError("%s: cannot set final field '%s'.",
-                             CURRENT_FUNC, field_name.ToCString());
-      } else {
-        field.set_value(value_instance);
-        return Api::Success();
-      }
-    } else {
-      return Api::NewError("%s: did not find static field '%s'.",
-                           CURRENT_FUNC, field_name.ToCString());
-    }
-
   } else if (obj.IsLibrary()) {
     // To access a top-level we may need to use the Field or the
     // setter Function.  The setter function may either be in the
@@ -3258,7 +3327,7 @@
       return container;
   } else {
     return Api::NewError(
-        "%s expects argument 'container' to be an object, class, or library.",
+        "%s expects argument 'container' to be an object, type, or library.",
         CURRENT_FUNC);
   }
 }
@@ -3619,6 +3688,82 @@
 }
 
 
+DART_EXPORT Dart_Handle Dart_GetType(Dart_Handle library,
+                                     Dart_Handle class_name,
+                                     intptr_t number_of_type_arguments,
+                                     Dart_Handle* type_arguments) {
+  Isolate* isolate = Isolate::Current();
+  DARTSCOPE(isolate);
+
+  // Validate the input arguments.
+  const Library& lib = Api::UnwrapLibraryHandle(isolate, library);
+  if (lib.IsNull()) {
+    RETURN_TYPE_ERROR(isolate, library, Library);
+  }
+  const String& name_str = Api::UnwrapStringHandle(isolate, class_name);
+  if (name_str.IsNull()) {
+    RETURN_TYPE_ERROR(isolate, class_name, String);
+  }
+  // Ensure all classes are finalized.
+  Dart_Handle state = Api::CheckIsolateState(isolate);
+  if (::Dart_IsError(state)) {
+    return state;
+  }
+  const Class& cls =
+      Class::Handle(isolate, lib.LookupClassAllowPrivate(name_str));
+  if (cls.IsNull()) {
+    const String& lib_name = String::Handle(isolate, lib.name());
+    return Api::NewError("Type '%s' not found in library '%s'.",
+                         name_str.ToCString(), lib_name.ToCString());
+  }
+  if (cls.NumTypeArguments() == 0) {
+    if (number_of_type_arguments != 0) {
+      return Api::NewError("Invalid number of type arguments specified, "
+                           "got %"Pd" expected 0", number_of_type_arguments);
+    }
+    return Api::NewHandle(isolate, Type::NewNonParameterizedType(cls));
+  }
+  intptr_t num_expected_type_arguments = cls.NumTypeParameters();
+  TypeArguments& type_args_obj = TypeArguments::Handle();
+  if (number_of_type_arguments > 0) {
+    if (type_arguments == NULL) {
+      RETURN_NULL_ERROR(type_arguments);
+    }
+    if (num_expected_type_arguments != number_of_type_arguments) {
+      return Api::NewError("Invalid number of type arguments specified, "
+                           "got %"Pd" expected %"Pd,
+                           number_of_type_arguments,
+                           num_expected_type_arguments);
+    }
+    const Array& array = Api::UnwrapArrayHandle(isolate, *type_arguments);
+    if (array.IsNull()) {
+      RETURN_TYPE_ERROR(isolate, *type_arguments, Array);
+    }
+    if (array.Length() != num_expected_type_arguments) {
+      return Api::NewError("Invalid type arguments specified, expected an "
+                           "array of len %"Pd" but got an array of len %"Pd,
+                           number_of_type_arguments,
+                           array.Length());
+    }
+    // Set up the type arguments array.
+    type_args_obj ^= TypeArguments::New(num_expected_type_arguments);
+    AbstractType& type_arg = AbstractType::Handle();
+    for (intptr_t i = 0; i < number_of_type_arguments; i++) {
+      type_arg ^= array.At(i);
+      type_args_obj.SetTypeAt(i, type_arg);
+    }
+  }
+
+  // Construct the type object, canonicalize it and return.
+  const Type& instantiated_type = Type::Handle(
+      Type::New(cls, type_args_obj, Scanner::kDummyTokenIndex));
+  ClassFinalizer::FinalizeType(cls,
+                               instantiated_type,
+                               ClassFinalizer::kCanonicalize);
+  return Api::NewHandle(isolate, instantiated_type.raw());
+}
+
+
 DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
@@ -3722,7 +3867,7 @@
   const String& prefix_symbol =
       String::Handle(isolate, Symbols::New(prefix_vm));
   const Namespace& import_ns = Namespace::Handle(
-      Namespace::New(import_vm, Array::Handle(), Array::Handle()));
+      Namespace::New(import_vm, Object::null_array(), Object::null_array()));
   if (prefix_vm.Length() == 0) {
     library_vm.AddImport(import_ns);
   } else {
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 36ca32d..2c78b52 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -242,6 +242,37 @@
 }
 
 
+TEST_CASE(InstanceGetType) {
+  Isolate* isolate = Isolate::Current();
+  // Get the handle from a valid instance handle.
+  Dart_Handle type = Dart_InstanceGetType(Dart_Null());
+  EXPECT_VALID(type);
+  EXPECT(Dart_IsType(type));
+  const Type& null_type_obj = Api::UnwrapTypeHandle(isolate, type);
+  EXPECT(null_type_obj.raw() == Type::NullType());
+
+  Dart_Handle instance = Dart_True();
+  type = Dart_InstanceGetType(instance);
+  EXPECT_VALID(type);
+  EXPECT(Dart_IsType(type));
+  const Type& bool_type_obj = Api::UnwrapTypeHandle(isolate, type);
+  EXPECT(bool_type_obj.raw() == Type::BoolType());
+
+  // Errors propagate.
+  Dart_Handle error = Dart_NewApiError("MyError");
+  Dart_Handle error_type = Dart_InstanceGetType(error);
+  EXPECT_ERROR(error_type, "MyError");
+
+  // Get the handle from a non-instance handle
+  Dart_Handle obj = Api::NewHandle(isolate,
+                                   isolate->object_store()->type_class());
+  Dart_Handle type_type = Dart_InstanceGetType(obj);
+  EXPECT_ERROR(type_type,
+               "Dart_InstanceGetType expects argument 'instance' to be of "
+               "type Instance.");
+}
+
+
 TEST_CASE(InstanceGetClass) {
   // Get the handle from a valid instance handle.
   Dart_Handle instance = Dart_True();
@@ -2711,11 +2742,11 @@
                "class 'SomeClass' is not a function-type class.");
 }
 
-#define CHECK_ABSTRACT_CLASS(handle, name)                                     \
+#define CHECK_CLASS(handle, name)                                              \
   {                                                                            \
     Dart_Handle tmp = (handle);                                                \
     EXPECT_VALID(tmp);                                                         \
-    EXPECT(Dart_IsAbstractClass(tmp));                                         \
+    EXPECT(Dart_IsClass(tmp));                                                 \
     Dart_Handle intf_name = Dart_ClassName(tmp);                               \
     EXPECT_VALID(intf_name);                                                   \
     const char* intf_name_cstr = "";                                           \
@@ -2758,7 +2789,7 @@
   len = -1;
   EXPECT_VALID(Dart_ClassGetInterfaceCount(cls1, &len));
   EXPECT_EQ(1, len);
-  CHECK_ABSTRACT_CLASS(Dart_ClassGetInterfaceAt(cls1, 0), "MyInterface1");
+  CHECK_CLASS(Dart_ClassGetInterfaceAt(cls1, 0), "MyInterface1");
 
   EXPECT_ERROR(Dart_ClassGetInterfaceAt(cls1, -1),
                "Dart_ClassGetInterfaceAt: argument 'index' out of bounds");
@@ -2770,8 +2801,8 @@
   EXPECT_EQ(2, len);
 
   // TODO(turnidge): The test relies on the ordering here.  Sort this.
-  CHECK_ABSTRACT_CLASS(Dart_ClassGetInterfaceAt(cls2, 0), "MyInterface0");
-  CHECK_ABSTRACT_CLASS(Dart_ClassGetInterfaceAt(cls2, 1), "MyInterface1");
+  CHECK_CLASS(Dart_ClassGetInterfaceAt(cls2, 0), "MyInterface0");
+  CHECK_CLASS(Dart_ClassGetInterfaceAt(cls2, 1), "MyInterface1");
 
   len = -1;
   EXPECT_VALID(Dart_ClassGetInterfaceCount(intf0, &len));
@@ -2780,7 +2811,7 @@
   len = -1;
   EXPECT_VALID(Dart_ClassGetInterfaceCount(intf1, &len));
   EXPECT_EQ(1, len);
-  CHECK_ABSTRACT_CLASS(Dart_ClassGetInterfaceAt(intf1, 0), "MyInterface0");
+  CHECK_CLASS(Dart_ClassGetInterfaceAt(intf1, 0), "MyInterface0");
 
   // Error cases.
   EXPECT_ERROR(Dart_ClassGetInterfaceCount(Dart_True(), &len),
@@ -2791,6 +2822,208 @@
 }
 
 
+TEST_CASE(TypeGetNonParamtericTypes) {
+  const char* kScriptChars =
+      "class MyClass0 {\n"
+      "}\n"
+      "\n"
+      "class MyClass1 implements MyInterface1 {\n"
+      "}\n"
+      "\n"
+      "class MyClass2 implements MyInterface0, MyInterface1 {\n"
+      "}\n"
+      "\n"
+      "abstract class MyInterface0 {\n"
+      "}\n"
+      "\n"
+      "abstract class MyInterface1 implements MyInterface0 {\n"
+      "}\n"
+      "MyClass0 getMyClass0() { return new MyClass0(); }\n"
+      "MyClass1 getMyClass1() { return new MyClass1(); }\n"
+      "MyClass2 getMyClass2() { return new MyClass2(); }\n"
+      "Type getMyClass0Type() { return new MyClass0().runtimeType; }\n"
+      "Type getMyClass1Type() { return new MyClass1().runtimeType; }\n"
+      "Type getMyClass2Type() { return new MyClass2().runtimeType; }\n";
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  bool instanceof = false;
+
+  // First get the type objects of these non parameterized types.
+  Dart_Handle type0 = Dart_GetType(lib, NewString("MyClass0"), 0, NULL);
+  EXPECT_VALID(type0);
+  Dart_Handle type1 = Dart_GetType(lib, NewString("MyClass1"), 0, NULL);
+  EXPECT_VALID(type1);
+  Dart_Handle type2 = Dart_GetType(lib, NewString("MyClass2"), 0, NULL);
+  EXPECT_VALID(type2);
+  Dart_Handle type3 = Dart_GetType(lib, NewString("MyInterface0"), 0, NULL);
+  EXPECT_VALID(type3);
+  Dart_Handle type4 = Dart_GetType(lib, NewString("MyInterface1"), 0, NULL);
+  EXPECT_VALID(type4);
+
+  // Now create objects of these non parameterized types and check
+  // that the validity of the type of the created object.
+  // MyClass0 type.
+  Dart_Handle type0_obj = Dart_Invoke(lib, NewString("getMyClass0"), 0, NULL);
+  EXPECT_VALID(type0_obj);
+  EXPECT_VALID(Dart_ObjectIsType(type0_obj, type0, &instanceof));
+  EXPECT(instanceof);
+  EXPECT_VALID(Dart_ObjectIsType(type0_obj, type1, &instanceof));
+  EXPECT(!instanceof);
+  EXPECT_VALID(Dart_ObjectIsType(type0_obj, type2, &instanceof));
+  EXPECT(!instanceof);
+  EXPECT_VALID(Dart_ObjectIsType(type0_obj, type3, &instanceof));
+  EXPECT(!instanceof);
+  EXPECT_VALID(Dart_ObjectIsType(type0_obj, type4, &instanceof));
+  EXPECT(!instanceof);
+  type0_obj = Dart_Invoke(lib, NewString("getMyClass0Type"), 0, NULL);
+  EXPECT_VALID(type0_obj);
+  EXPECT(Dart_IdentityEquals(type0, type0_obj));
+
+  // MyClass1 type.
+  Dart_Handle type1_obj = Dart_Invoke(lib, NewString("getMyClass1"), 0, NULL);
+  EXPECT_VALID(type1_obj);
+  EXPECT_VALID(Dart_ObjectIsType(type1_obj, type1, &instanceof));
+  EXPECT(instanceof);
+  EXPECT_VALID(Dart_ObjectIsType(type1_obj, type0, &instanceof));
+  EXPECT(!instanceof);
+  EXPECT_VALID(Dart_ObjectIsType(type1_obj, type2, &instanceof));
+  EXPECT(!instanceof);
+  EXPECT_VALID(Dart_ObjectIsType(type1_obj, type3, &instanceof));
+  EXPECT(instanceof);
+  EXPECT_VALID(Dart_ObjectIsType(type1_obj, type4, &instanceof));
+  EXPECT(instanceof);
+  type1_obj = Dart_Invoke(lib, NewString("getMyClass1Type"), 0, NULL);
+  EXPECT_VALID(type1_obj);
+  EXPECT(Dart_IdentityEquals(type1, type1_obj));
+
+  // MyClass2 type.
+  Dart_Handle type2_obj = Dart_Invoke(lib, NewString("getMyClass2"), 0, NULL);
+  EXPECT_VALID(type2_obj);
+  EXPECT_VALID(Dart_ObjectIsType(type2_obj, type2, &instanceof));
+  EXPECT(instanceof);
+  EXPECT_VALID(Dart_ObjectIsType(type2_obj, type0, &instanceof));
+  EXPECT(!instanceof);
+  EXPECT_VALID(Dart_ObjectIsType(type2_obj, type1, &instanceof));
+  EXPECT(!instanceof);
+  EXPECT_VALID(Dart_ObjectIsType(type2_obj, type3, &instanceof));
+  EXPECT(instanceof);
+  EXPECT_VALID(Dart_ObjectIsType(type2_obj, type4, &instanceof));
+  EXPECT(instanceof);
+  type2_obj = Dart_Invoke(lib, NewString("getMyClass2Type"), 0, NULL);
+  EXPECT_VALID(type2_obj);
+  EXPECT(Dart_IdentityEquals(type2, type2_obj));
+}
+
+
+TEST_CASE(TypeGetParamterizedTypes) {
+  const char* kScriptChars =
+      "class MyClass0<A, B> {\n"
+      "}\n"
+      "\n"
+      "class MyClass1<A, C> {\n"
+      "}\n"
+      "MyClass0 getMyClass0() {\n"
+      "  return new MyClass0<int, double>();\n"
+      "}\n"
+      "Type getMyClass0Type() {\n"
+      "  return new MyClass0<int, double>().runtimeType;\n"
+      "}\n"
+      "MyClass1 getMyClass1() {\n"
+      "  return new MyClass1<List<int>, List>();\n"
+      "}\n"
+      "Type getMyClass1Type() {\n"
+      "  return new MyClass1<List<int>, List>().runtimeType;\n"
+      "}\n"
+      "MyClass0 getMyClass0_1() {\n"
+      "  return new MyClass0<double, int>();\n"
+      "}\n"
+      "Type getMyClass0_1Type() {\n"
+      "  return new MyClass0<double, int>().runtimeType;\n"
+      "}\n"
+      "MyClass1 getMyClass1_1() {\n"
+      "  return new MyClass1<List<int>, List<double>>();\n"
+      "}\n"
+      "Type getMyClass1_1Type() {\n"
+      "  return new MyClass1<List<int>, List<double>>().runtimeType;\n"
+      "}\n";
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  bool instanceof = false;
+
+  // First get type objects of some of the basic types used in the test.
+  Dart_Handle int_type = Dart_GetType(lib, NewString("int"), 0, NULL);
+  EXPECT_VALID(int_type);
+  Dart_Handle double_type = Dart_GetType(lib, NewString("double"), 0, NULL);
+  EXPECT_VALID(double_type);
+  Dart_Handle list_type = Dart_GetType(lib, NewString("List"), 0, NULL);
+  EXPECT_VALID(list_type);
+  Dart_Handle type_args = Dart_NewList(1);
+  EXPECT_VALID(Dart_ListSetAt(type_args, 0, int_type));
+  Dart_Handle list_int_type = Dart_GetType(lib,
+                                           NewString("List"),
+                                           1,
+                                           &type_args);
+  EXPECT_VALID(list_int_type);
+
+  // Now instantiate MyClass0 and MyClass1 types with the same type arguments
+  // used in the code above.
+  type_args = Dart_NewList(2);
+  EXPECT_VALID(Dart_ListSetAt(type_args, 0, int_type));
+  EXPECT_VALID(Dart_ListSetAt(type_args, 1, double_type));
+  Dart_Handle myclass0_type = Dart_GetType(lib,
+                                           NewString("MyClass0"),
+                                           2,
+                                           &type_args);
+  EXPECT_VALID(myclass0_type);
+
+  type_args = Dart_NewList(2);
+  EXPECT_VALID(Dart_ListSetAt(type_args, 0, list_int_type));
+  EXPECT_VALID(Dart_ListSetAt(type_args, 1, list_type));
+  Dart_Handle myclass1_type = Dart_GetType(lib,
+                                           NewString("MyClass1"),
+                                           2,
+                                           &type_args);
+  EXPECT_VALID(myclass1_type);
+
+  // Now create objects of the type and validate the object type matches
+  // the one returned above. Also get the runtime type of the object and
+  // verify that it matches the type returned above.
+  // MyClass0<int, double> type.
+  Dart_Handle type0_obj = Dart_Invoke(lib, NewString("getMyClass0"), 0, NULL);
+  EXPECT_VALID(type0_obj);
+  EXPECT_VALID(Dart_ObjectIsType(type0_obj, myclass0_type, &instanceof));
+  EXPECT(instanceof);
+  type0_obj = Dart_Invoke(lib, NewString("getMyClass0Type"), 0, NULL);
+  EXPECT_VALID(type0_obj);
+  EXPECT(Dart_IdentityEquals(type0_obj, myclass0_type));
+
+  // MyClass1<List<int>, List> type.
+  Dart_Handle type1_obj = Dart_Invoke(lib, NewString("getMyClass1"), 0, NULL);
+  EXPECT_VALID(type1_obj);
+  EXPECT_VALID(Dart_ObjectIsType(type1_obj, myclass1_type, &instanceof));
+  EXPECT(instanceof);
+  type1_obj = Dart_Invoke(lib, NewString("getMyClass1Type"), 0, NULL);
+  EXPECT_VALID(type1_obj);
+  EXPECT(Dart_IdentityEquals(type1_obj, myclass1_type));
+
+  // MyClass0<double, int> type.
+  type0_obj = Dart_Invoke(lib, NewString("getMyClass0_1"), 0, NULL);
+  EXPECT_VALID(type0_obj);
+  EXPECT_VALID(Dart_ObjectIsType(type0_obj, myclass0_type, &instanceof));
+  EXPECT(!instanceof);
+  type0_obj = Dart_Invoke(lib, NewString("getMyClass0_1Type"), 0, NULL);
+  EXPECT_VALID(type0_obj);
+  EXPECT(!Dart_IdentityEquals(type0_obj, myclass0_type));
+
+  // MyClass1<List<int>, List<double>> type.
+  type1_obj = Dart_Invoke(lib, NewString("getMyClass1_1"), 0, NULL);
+  EXPECT_VALID(type1_obj);
+  EXPECT_VALID(Dart_ObjectIsType(type1_obj, myclass1_type, &instanceof));
+  EXPECT(instanceof);
+  type1_obj = Dart_Invoke(lib, NewString("getMyClass1_1Type"), 0, NULL);
+  EXPECT_VALID(type1_obj);
+  EXPECT(!Dart_IdentityEquals(type1_obj, myclass1_type));
+}
+
+
 static void TestFieldOk(Dart_Handle container,
                         Dart_Handle name,
                         bool final,
@@ -2923,8 +3156,8 @@
 
   // Shared setup.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  Dart_Handle cls = Dart_GetClass(lib, NewString("Fields"));
-  EXPECT_VALID(cls);
+  Dart_Handle type = Dart_GetType(lib, NewString("Fields"), 0, NULL);
+  EXPECT_VALID(type);
   Dart_Handle instance = Dart_Invoke(lib, NewString("test"), 0, NULL);
   EXPECT_VALID(instance);
   Dart_Handle name;
@@ -2943,144 +3176,144 @@
   // Instance field.
   name = NewString("instance_fld");
   TestFieldNotFound(lib, name);
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldOk(instance, name, false, "instance");
 
   // Hidden instance field.
   name = NewString("_instance_fld");
   TestFieldNotFound(lib, name);
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldOk(instance, name, false, "hidden instance");
 
   // Final instance field.
   name = NewString("final_instance_fld");
   TestFieldNotFound(lib, name);
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldOk(instance, name, true, "final instance");
 
   // Hidden final instance field.
   name = NewString("_final_instance_fld");
   TestFieldNotFound(lib, name);
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldOk(instance, name, true, "hidden final instance");
 
   // Inherited field.
   name = NewString("inherited_fld");
   TestFieldNotFound(lib, name);
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldOk(instance, name, false, "inherited");
 
   // Instance get/set field.
   name = NewString("instance_getset_fld");
   TestFieldNotFound(lib, name);
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldOk(instance, name, false, "instance getset");
 
   // Hidden instance get/set field.
   name = NewString("_instance_getset_fld");
   TestFieldNotFound(lib, name);
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldOk(instance, name, false, "hidden instance getset");
 
   // Static field.
   name = NewString("static_fld");
   TestFieldNotFound(lib, name);
   TestFieldNotFound(instance, name);
-  TestFieldOk(cls, name, false, "static");
+  TestFieldOk(type, name, false, "static");
 
   // Hidden static field.
   name = NewString("_static_fld");
   TestFieldNotFound(lib, name);
   TestFieldNotFound(instance, name);
-  TestFieldOk(cls, name, false, "hidden static");
+  TestFieldOk(type, name, false, "hidden static");
 
   // Static final field.
   name = NewString("const_static_fld");
   TestFieldNotFound(lib, name);
   TestFieldNotFound(instance, name);
-  TestFieldOk(cls, name, true, "const static");
+  TestFieldOk(type, name, true, "const static");
 
   // Hidden static const field.
   name = NewString("_const_static_fld");
   TestFieldNotFound(lib, name);
   TestFieldNotFound(instance, name);
-  TestFieldOk(cls, name, true, "hidden const static");
+  TestFieldOk(type, name, true, "hidden const static");
 
   // Static non-inherited field.  Not found at any level.
   name = NewString("non_inherited_fld");
   TestFieldNotFound(lib, name);
   TestFieldNotFound(instance, name);
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
 
   // Static get/set field.
   name = NewString("static_getset_fld");
   TestFieldNotFound(lib, name);
   TestFieldNotFound(instance, name);
-  TestFieldOk(cls, name, false, "static getset");
+  TestFieldOk(type, name, false, "static getset");
 
   // Hidden static get/set field.
   name = NewString("_static_getset_fld");
   TestFieldNotFound(lib, name);
   TestFieldNotFound(instance, name);
-  TestFieldOk(cls, name, false, "hidden static getset");
+  TestFieldOk(type, name, false, "hidden static getset");
 
   // Top-Level field.
   name = NewString("top_fld");
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldNotFound(instance, name);
   TestFieldOk(lib, name, false, "top");
 
   // Hidden top-level field.
   name = NewString("_top_fld");
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldNotFound(instance, name);
   TestFieldOk(lib, name, false, "hidden top");
 
   // Top-Level final field.
   name = NewString("const_top_fld");
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldNotFound(instance, name);
   TestFieldOk(lib, name, true, "const top");
 
   // Hidden top-level final field.
   name = NewString("_const_top_fld");
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldNotFound(instance, name);
   TestFieldOk(lib, name, true, "hidden const top");
 
   // Top-Level get/set field.
   name = NewString("top_getset_fld");
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldNotFound(instance, name);
   TestFieldOk(lib, name, false, "top getset");
 
   // Hidden top-level get/set field.
   name = NewString("_top_getset_fld");
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldNotFound(instance, name);
   TestFieldOk(lib, name, false, "hidden top getset");
 
   // Imported top-Level field.
   name = NewString("imported_fld");
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldNotFound(instance, name);
   TestFieldOk(lib, name, false, "imported");
 
   // Hidden imported top-level field.  Not found at any level.
   name = NewString("_imported_fld");
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldNotFound(instance, name);
   TestFieldNotFound(lib, name);
 
   // Imported top-Level get/set field.
   name = NewString("imported_getset_fld");
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldNotFound(instance, name);
   TestFieldOk(lib, name, false, "imported getset");
 
   // Hidden imported top-level get/set field.  Not found at any level.
   name = NewString("_imported_getset_fld");
-  TestFieldNotFound(cls, name);
+  TestFieldNotFound(type, name);
   TestFieldNotFound(instance, name);
   TestFieldNotFound(lib, name);
 }
@@ -3588,33 +3821,33 @@
   Dart_Handle result;
   // Create a test library and Load up a test script in it.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  Dart_Handle cls = Dart_GetClass(lib, NewString("TestClass"));
-  EXPECT_VALID(cls);
+  Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL);
+  EXPECT_VALID(type);
 
   // Invoke a function which returns an object.
-  result = Dart_Invoke(cls, NewString("testMain"), 0, NULL);
+  result = Dart_Invoke(type, NewString("testMain"), 0, NULL);
   EXPECT_VALID(result);
 
   // For uninitialized fields, the getter is returned
-  result = Dart_GetField(cls, NewString("fld1"));
+  result = Dart_GetField(type, NewString("fld1"));
   EXPECT_VALID(result);
   int64_t value = 0;
   result = Dart_IntegerToInt64(result, &value);
   EXPECT_EQ(7, value);
 
-  result = Dart_GetField(cls, NewString("fld2"));
+  result = Dart_GetField(type, NewString("fld2"));
   EXPECT_VALID(result);
   result = Dart_IntegerToInt64(result, &value);
   EXPECT_EQ(11, value);
 
   // Overwrite fld2
-  result = Dart_SetField(cls,
+  result = Dart_SetField(type,
                          NewString("fld2"),
                          Dart_NewInteger(13));
   EXPECT_VALID(result);
 
   // We now get the new value for fld2, not the initializer
-  result = Dart_GetField(cls, NewString("fld2"));
+  result = Dart_GetField(type, NewString("fld2"));
   EXPECT_VALID(result);
   result = Dart_IntegerToInt64(result, &value);
   EXPECT_EQ(13, value);
@@ -3633,10 +3866,10 @@
 
   // Create a test library and Load up a test script in it.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  Dart_Handle cls = Dart_GetClass(lib, NewString("TestClass"));
-  EXPECT_VALID(cls);
+  Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL);
+  EXPECT_VALID(type);
 
-  result = Dart_GetField(cls, NewString("fld2"));
+  result = Dart_GetField(type, NewString("fld2"));
   EXPECT_VALID(result);
   result = Dart_IntegerToInt64(result, &value);
   EXPECT_EQ(11, value);
@@ -3655,13 +3888,13 @@
 
   // Create a test library and Load up a test script in it.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  Dart_Handle cls = Dart_GetClass(lib, NewString("TestClass"));
-  EXPECT_VALID(cls);
+  Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL);
+  EXPECT_VALID(type);
 
-  result = Dart_SetField(cls, NewString("fld2"), Dart_NewInteger(13));
+  result = Dart_SetField(type, NewString("fld2"), Dart_NewInteger(13));
   EXPECT_VALID(result);
 
-  result = Dart_GetField(cls, NewString("fld2"));
+  result = Dart_GetField(type, NewString("fld2"));
   EXPECT_VALID(result);
   result = Dart_IntegerToInt64(result, &value);
   EXPECT_EQ(13, value);
@@ -3697,9 +3930,9 @@
       "}\n";
 
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  Dart_Handle cls = Dart_GetClass(lib, NewString("MyClass"));
-  EXPECT_VALID(cls);
-  Dart_Handle intf = Dart_GetClass(lib, NewString("MyInterface"));
+  Dart_Handle type = Dart_GetType(lib, NewString("MyClass"), 0, NULL);
+  EXPECT_VALID(type);
+  Dart_Handle intf = Dart_GetType(lib, NewString("MyInterface"), 0, NULL);
   EXPECT_VALID(intf);
   Dart_Handle args[1];
   args[0] = Dart_NewInteger(11);
@@ -3707,21 +3940,30 @@
   bad_args[0] = Dart_Error("myerror");
 
   // Invoke the unnamed constructor.
-  Dart_Handle result = Dart_New(cls, Dart_Null(), 0, NULL);
+  Dart_Handle result = Dart_New(type, Dart_Null(), 0, NULL);
   EXPECT_VALID(result);
   bool instanceof = false;
-  EXPECT_VALID(Dart_ObjectIsType(result, cls, &instanceof));
+  EXPECT_VALID(Dart_ObjectIsType(result, type, &instanceof));
   EXPECT(instanceof);
   int64_t int_value = 0;
   Dart_Handle foo = Dart_GetField(result, NewString("foo"));
   EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
   EXPECT_EQ(7, int_value);
 
-  // Invoke the unnamed constructor with an empty string.
-  result = Dart_New(cls, NewString(""), 0, NULL);
+  // Allocate without a constructor.
+  result = Dart_Allocate(type);
   EXPECT_VALID(result);
   instanceof = false;
-  EXPECT_VALID(Dart_ObjectIsType(result, cls, &instanceof));
+  EXPECT_VALID(Dart_ObjectIsType(result, type, &instanceof));
+  EXPECT(instanceof);
+  foo = Dart_GetField(result, NewString("foo"));
+  EXPECT(Dart_IsNull(foo));
+
+  // Invoke the unnamed constructor with an empty string.
+  result = Dart_New(type, NewString(""), 0, NULL);
+  EXPECT_VALID(result);
+  instanceof = false;
+  EXPECT_VALID(Dart_ObjectIsType(result, type, &instanceof));
   EXPECT(instanceof);
   int_value = 0;
   foo = Dart_GetField(result, NewString("foo"));
@@ -3729,9 +3971,9 @@
   EXPECT_EQ(7, int_value);
 
   // Invoke a named constructor.
-  result = Dart_New(cls, NewString("named"), 1, args);
+  result = Dart_New(type, NewString("named"), 1, args);
   EXPECT_VALID(result);
-  EXPECT_VALID(Dart_ObjectIsType(result, cls, &instanceof));
+  EXPECT_VALID(Dart_ObjectIsType(result, type, &instanceof));
   EXPECT(instanceof);
   int_value = 0;
   foo = Dart_GetField(result, NewString("foo"));
@@ -3739,9 +3981,9 @@
   EXPECT_EQ(11, int_value);
 
   // Invoke a hidden named constructor.
-  result = Dart_New(cls, NewString("_hidden"), 1, args);
+  result = Dart_New(type, NewString("_hidden"), 1, args);
   EXPECT_VALID(result);
-  EXPECT_VALID(Dart_ObjectIsType(result, cls, &instanceof));
+  EXPECT_VALID(Dart_ObjectIsType(result, type, &instanceof));
   EXPECT(instanceof);
   int_value = 0;
   foo = Dart_GetField(result, NewString("foo"));
@@ -3749,9 +3991,9 @@
   EXPECT_EQ(-11, int_value);
 
   // Invoke a factory constructor.
-  result = Dart_New(cls, NewString("multiply"), 1, args);
+  result = Dart_New(type, NewString("multiply"), 1, args);
   EXPECT_VALID(result);
-  EXPECT_VALID(Dart_ObjectIsType(result, cls, &instanceof));
+  EXPECT_VALID(Dart_ObjectIsType(result, type, &instanceof));
   EXPECT(instanceof);
   int_value = 0;
   foo = Dart_GetField(result, NewString("foo"));
@@ -3759,7 +4001,7 @@
   EXPECT_EQ(1100, int_value);
 
   // Invoke a factory constructor which returns null.
-  result = Dart_New(cls, NewString("nullo"), 0, NULL);
+  result = Dart_New(type, NewString("nullo"), 0, NULL);
   EXPECT_VALID(result);
   EXPECT(Dart_IsNull(result));
 
@@ -3769,44 +4011,44 @@
 
   // Pass a bad class object.
   result = Dart_New(Dart_Null(), NewString("named"), 1, args);
-  EXPECT_ERROR(result, "Dart_New expects argument 'clazz' to be non-null.");
+  EXPECT_ERROR(result, "Dart_New expects argument 'type' to be non-null.");
 
   // Pass a negative arg count.
-  result = Dart_New(cls, NewString("named"), -1, args);
+  result = Dart_New(type, NewString("named"), -1, args);
   EXPECT_ERROR(
       result,
       "Dart_New expects argument 'number_of_arguments' to be non-negative.");
 
   // Pass the wrong arg count.
-  result = Dart_New(cls, NewString("named"), 0, NULL);
+  result = Dart_New(type, NewString("named"), 0, NULL);
   EXPECT_ERROR(
       result,
       "Dart_New: wrong argument count for constructor 'MyClass.named': "
       "0 passed, 1 expected.");
 
   // Pass a bad argument.  Error is passed through.
-  result = Dart_New(cls, NewString("named"), 1, bad_args);
+  result = Dart_New(type, NewString("named"), 1, bad_args);
   EXPECT_ERROR(result, "myerror");
 
   // Pass a bad constructor name.
-  result = Dart_New(cls, Dart_NewInteger(55), 1, args);
+  result = Dart_New(type, Dart_NewInteger(55), 1, args);
   EXPECT_ERROR(
       result,
       "Dart_New expects argument 'constructor_name' to be of type String.");
 
   // Invoke a missing constructor.
-  result = Dart_New(cls, NewString("missing"), 1, args);
+  result = Dart_New(type, NewString("missing"), 1, args);
   EXPECT_ERROR(result,
                "Dart_New: could not find constructor 'MyClass.missing'.");
 
   // Invoke a constructor which throws an exception.
-  result = Dart_New(cls, NewString("exception"), 1, args);
+  result = Dart_New(type, NewString("exception"), 1, args);
   EXPECT_ERROR(result, "ConstructorDeath");
 
   // Invoke two-hop redirecting factory constructor.
   result = Dart_New(intf, NewString("named"), 1, args);
   EXPECT_VALID(result);
-  EXPECT_VALID(Dart_ObjectIsType(result, cls, &instanceof));
+  EXPECT_VALID(Dart_ObjectIsType(result, type, &instanceof));
   EXPECT(instanceof);
   int_value = 0;
   foo = Dart_GetField(result, NewString("foo"));
@@ -3816,7 +4058,7 @@
   // Invoke one-hop redirecting factory constructor.
   result = Dart_New(intf, NewString("multiply"), 1, args);
   EXPECT_VALID(result);
-  EXPECT_VALID(Dart_ObjectIsType(result, cls, &instanceof));
+  EXPECT_VALID(Dart_ObjectIsType(result, type, &instanceof));
   EXPECT(instanceof);
   int_value = 0;
   foo = Dart_GetField(result, NewString("foo"));
@@ -3831,7 +4073,7 @@
   // Invoke abstract constructor that is present in the interface.
   result = Dart_New(intf, NewString("notfound"), 1, args);
   EXPECT_VALID(result);
-  EXPECT_VALID(Dart_ObjectIsType(result, cls, &instanceof));
+  EXPECT_VALID(Dart_ObjectIsType(result, type, &instanceof));
   EXPECT(!instanceof);
 }
 
@@ -3842,13 +4084,13 @@
   // factories.
   Dart_Handle core_lib = Dart_LookupLibrary(NewString("dart:core"));
   EXPECT_VALID(core_lib);
-  Dart_Handle list_class = Dart_GetClass(core_lib, NewString("List"));
-  EXPECT_VALID(list_class);
+  Dart_Handle list_type = Dart_GetType(core_lib, NewString("List"), 0, NULL);
+  EXPECT_VALID(list_type);
 
   const int kNumArgs = 1;
   Dart_Handle args[kNumArgs];
   args[0] = Dart_NewInteger(1);
-  Dart_Handle list_obj = Dart_New(list_class, Dart_Null(), kNumArgs, args);
+  Dart_Handle list_obj = Dart_New(list_type, Dart_Null(), kNumArgs, args);
   EXPECT_VALID(list_obj);
   EXPECT(Dart_IsList(list_obj));
 }
@@ -3886,8 +4128,8 @@
 
   // Shared setup.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  Dart_Handle cls = Dart_GetClass(lib, NewString("Methods"));
-  EXPECT_VALID(cls);
+  Dart_Handle type = Dart_GetType(lib, NewString("Methods"), 0, NULL);
+  EXPECT_VALID(type);
   Dart_Handle instance = Dart_Invoke(lib, NewString("test"), 0, NULL);
   EXPECT_VALID(instance);
   Dart_Handle args[1];
@@ -3902,7 +4144,7 @@
   // Instance method.
   name = NewString("instanceMethod");
   EXPECT(Dart_IsError(Dart_Invoke(lib, name, 1, args)));
-  EXPECT(Dart_IsError(Dart_Invoke(cls, name, 1, args)));
+  EXPECT(Dart_IsError(Dart_Invoke(type, name, 1, args)));
   result = Dart_Invoke(instance, name, 1, args);
   EXPECT_VALID(result);
   result = Dart_StringToCString(result, &str);
@@ -3915,7 +4157,7 @@
 
   name = PrivateLibName(lib, "_instanceMethod");
   EXPECT(Dart_IsError(Dart_Invoke(lib, name, 1, args)));
-  EXPECT(Dart_IsError(Dart_Invoke(cls, name, 1, args)));
+  EXPECT(Dart_IsError(Dart_Invoke(type, name, 1, args)));
   result = Dart_Invoke(instance, name, 1, args);
   EXPECT_VALID(result);
   result = Dart_StringToCString(result, &str);
@@ -3924,7 +4166,7 @@
   // Inherited method.
   name = NewString("inheritedMethod");
   EXPECT(Dart_IsError(Dart_Invoke(lib, name, 1, args)));
-  EXPECT(Dart_IsError(Dart_Invoke(cls, name, 1, args)));
+  EXPECT(Dart_IsError(Dart_Invoke(type, name, 1, args)));
   result = Dart_Invoke(instance, name, 1, args);
   EXPECT_VALID(result);
   result = Dart_StringToCString(result, &str);
@@ -3934,20 +4176,20 @@
   name = NewString("staticMethod");
   EXPECT(Dart_IsError(Dart_Invoke(lib, name, 1, args)));
   EXPECT(Dart_IsError(Dart_Invoke(instance, name, 1, args)));
-  result = Dart_Invoke(cls, name, 1, args);
+  result = Dart_Invoke(type, name, 1, args);
   EXPECT_VALID(result);
   result = Dart_StringToCString(result, &str);
   EXPECT_STREQ("static !!!", str);
 
   // Static method, wrong arg count.
-  EXPECT_ERROR(Dart_Invoke(cls, name, 2, bad_args),
+  EXPECT_ERROR(Dart_Invoke(type, name, 2, bad_args),
                "did not find static method 'Methods.staticMethod'");
 
   // Hidden static method.
   name = PrivateLibName(lib, "_staticMethod");
   EXPECT(Dart_IsError(Dart_Invoke(lib, name, 1, args)));
   EXPECT(Dart_IsError(Dart_Invoke(instance, name, 1, args)));
-  result = Dart_Invoke(cls, name, 1, args);
+  result = Dart_Invoke(type, name, 1, args);
   EXPECT_VALID(result);
   result = Dart_StringToCString(result, &str);
   EXPECT_STREQ("hidden static !!!", str);
@@ -3956,11 +4198,11 @@
   name = NewString("non_inheritedMethod");
   EXPECT(Dart_IsError(Dart_Invoke(lib, name, 1, args)));
   EXPECT(Dart_IsError(Dart_Invoke(instance, name, 1, args)));
-  EXPECT(Dart_IsError(Dart_Invoke(cls, name, 1, args)));
+  EXPECT(Dart_IsError(Dart_Invoke(type, name, 1, args)));
 
   // Top-Level method.
   name = NewString("topMethod");
-  EXPECT(Dart_IsError(Dart_Invoke(cls, name, 1, args)));
+  EXPECT(Dart_IsError(Dart_Invoke(type, name, 1, args)));
   EXPECT(Dart_IsError(Dart_Invoke(instance, name, 1, args)));
   result = Dart_Invoke(lib, name, 1, args);
   EXPECT_VALID(result);
@@ -3974,7 +4216,7 @@
 
   // Hidden top-level method.
   name = PrivateLibName(lib, "_topMethod");
-  EXPECT(Dart_IsError(Dart_Invoke(cls, name, 1, args)));
+  EXPECT(Dart_IsError(Dart_Invoke(type, name, 1, args)));
   EXPECT(Dart_IsError(Dart_Invoke(instance, name, 1, args)));
   result = Dart_Invoke(lib, name, 1, args);
   EXPECT_VALID(result);
@@ -4091,11 +4333,11 @@
   Dart_Handle instance;
   // Create a test library and Load up a test script in it.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  Dart_Handle cls = Dart_GetClass(lib, NewString("TestClass"));
-  EXPECT_VALID(cls);
+  Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL);
+  EXPECT_VALID(type);
 
   // Invoke a function which returns an object.
-  instance = Dart_Invoke(cls, NewString("testMain"), 0, NULL);
+  instance = Dart_Invoke(type, NewString("testMain"), 0, NULL);
   EXPECT_VALID(instance);
 
   // Try to get a field that does not exist, should call noSuchMethod.
@@ -4110,7 +4352,7 @@
   result = Dart_Invoke(instance, NewString("method"), 0, NULL);
   EXPECT_VALID(result);
 
-  result = Dart_GetField(cls, NewString("fld1"));
+  result = Dart_GetField(type, NewString("fld1"));
   EXPECT_VALID(result);
   int64_t value = 0;
   result = Dart_IntegerToInt64(result, &value);
@@ -4193,8 +4435,8 @@
   // Create a test library and Load up a test script in it.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
   EXPECT_VALID(lib);
-  Dart_Handle cls = Dart_GetClass(lib, NewString("Foo"));
-  EXPECT_VALID(cls);
+  Dart_Handle type = Dart_GetType(lib, NewString("Foo"), 0, NULL);
+  EXPECT_VALID(type);
 
   // Invoke a function which returns a closure.
   Dart_Handle retobj = Dart_Invoke(lib, NewString("getClosure"), 0, NULL);
@@ -4235,6 +4477,9 @@
   EXPECT(Dart_IsFunction(result));
   owner = Dart_FunctionOwner(result);
   EXPECT_VALID(owner);
+  Isolate* isolate = Isolate::Current();
+  Dart_Handle cls = Api::NewHandle(
+      isolate, Api::UnwrapTypeHandle(isolate, type).type_class());
   defining_function = Dart_LookupFunction(cls,
                                           NewString("getInstanceClosure"));
   EXPECT(Dart_IdentityEquals(owner, defining_function));
@@ -4479,7 +4724,7 @@
 }
 
 
-TEST_CASE(GetClass) {
+TEST_CASE(GetType) {
   const char* kScriptChars =
       "class Class {\n"
       "  static var name = 'Class';\n"
@@ -4492,38 +4737,38 @@
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
 
   // Lookup a class.
-  Dart_Handle cls = Dart_GetClass(lib, NewString("Class"));
-  EXPECT_VALID(cls);
-  Dart_Handle name = Dart_GetField(cls, NewString("name"));
+  Dart_Handle type = Dart_GetType(lib, NewString("Class"), 0, NULL);
+  EXPECT_VALID(type);
+  Dart_Handle name = Dart_GetField(type, NewString("name"));
   EXPECT_VALID(name);
   const char* name_cstr = "";
   EXPECT_VALID(Dart_StringToCString(name, &name_cstr));
   EXPECT_STREQ("Class", name_cstr);
 
   // Lookup a private class.
-  cls = Dart_GetClass(lib, NewString("_Class"));
-  EXPECT_VALID(cls);
-  name = Dart_GetField(cls, NewString("name"));
+  type = Dart_GetType(lib, NewString("_Class"), 0, NULL);
+  EXPECT_VALID(type);
+  name = Dart_GetField(type, NewString("name"));
   EXPECT_VALID(name);
   name_cstr = "";
   EXPECT_VALID(Dart_StringToCString(name, &name_cstr));
   EXPECT_STREQ("_Class", name_cstr);
 
   // Lookup a class that does not exist.
-  cls = Dart_GetClass(lib, NewString("DoesNotExist"));
-  EXPECT(Dart_IsError(cls));
-  EXPECT_STREQ("Class 'DoesNotExist' not found in library 'dart:test-lib'.",
-               Dart_GetError(cls));
+  type = Dart_GetType(lib, NewString("DoesNotExist"), 0, NULL);
+  EXPECT(Dart_IsError(type));
+  EXPECT_STREQ("Type 'DoesNotExist' not found in library 'dart:test-lib'.",
+               Dart_GetError(type));
 
   // Lookup a class from an error library.  The error propagates.
-  cls = Dart_GetClass(Api::NewError("myerror"), NewString("Class"));
-  EXPECT(Dart_IsError(cls));
-  EXPECT_STREQ("myerror", Dart_GetError(cls));
+  type = Dart_GetType(Api::NewError("myerror"), NewString("Class"), 0, NULL);
+  EXPECT(Dart_IsError(type));
+  EXPECT_STREQ("myerror", Dart_GetError(type));
 
-  // Lookup a class using an error class name.  The error propagates.
-  cls = Dart_GetClass(lib, Api::NewError("myerror"));
-  EXPECT(Dart_IsError(cls));
-  EXPECT_STREQ("myerror", Dart_GetError(cls));
+  // Lookup a type using an error class name.  The error propagates.
+  type = Dart_GetType(lib, Api::NewError("myerror"), 0, NULL);
+  EXPECT(Dart_IsError(type));
+  EXPECT_STREQ("myerror", Dart_GetError(type));
 }
 
 
@@ -5221,51 +5466,51 @@
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
 
   // Fetch InstanceOfTest class.
-  Dart_Handle cls = Dart_GetClass(lib, NewString("InstanceOfTest"));
-  EXPECT_VALID(cls);
+  Dart_Handle type = Dart_GetType(lib, NewString("InstanceOfTest"), 0, NULL);
+  EXPECT_VALID(type);
 
   // Invoke a function which returns an object of type InstanceOf..
   Dart_Handle instanceOfTestObj =
-      Dart_Invoke(cls, NewString("testMain"), 0, NULL);
+      Dart_Invoke(type, NewString("testMain"), 0, NULL);
   EXPECT_VALID(instanceOfTestObj);
 
   // Now check instanceOfTestObj reported as an instance of
   // InstanceOfTest class.
   bool is_instance = false;
-  result = Dart_ObjectIsType(instanceOfTestObj, cls, &is_instance);
+  result = Dart_ObjectIsType(instanceOfTestObj, type, &is_instance);
   EXPECT_VALID(result);
   EXPECT(is_instance);
 
   // Fetch OtherClass and check if instanceOfTestObj is instance of it.
-  Dart_Handle otherClass = Dart_GetClass(lib, NewString("OtherClass"));
-  EXPECT_VALID(otherClass);
+  Dart_Handle otherType = Dart_GetType(lib, NewString("OtherClass"), 0, NULL);
+  EXPECT_VALID(otherType);
 
-  result = Dart_ObjectIsType(instanceOfTestObj, otherClass, &is_instance);
+  result = Dart_ObjectIsType(instanceOfTestObj, otherType, &is_instance);
   EXPECT_VALID(result);
   EXPECT(!is_instance);
 
   // Check that primitives are not instances of InstanceOfTest class.
-  result = Dart_ObjectIsType(NewString("a string"), otherClass,
+  result = Dart_ObjectIsType(NewString("a string"), otherType,
                              &is_instance);
   EXPECT_VALID(result);
   EXPECT(!is_instance);
 
-  result = Dart_ObjectIsType(Dart_NewInteger(42), otherClass, &is_instance);
+  result = Dart_ObjectIsType(Dart_NewInteger(42), otherType, &is_instance);
   EXPECT_VALID(result);
   EXPECT(!is_instance);
 
-  result = Dart_ObjectIsType(Dart_NewBoolean(true), otherClass, &is_instance);
+  result = Dart_ObjectIsType(Dart_NewBoolean(true), otherType, &is_instance);
   EXPECT_VALID(result);
   EXPECT(!is_instance);
 
   // Check that null is not an instance of InstanceOfTest class.
-  Dart_Handle null = Dart_Invoke(otherClass,
+  Dart_Handle null = Dart_Invoke(otherType,
                                  NewString("returnNull"),
                                  0,
                                  NULL);
   EXPECT_VALID(null);
 
-  result = Dart_ObjectIsType(null, otherClass, &is_instance);
+  result = Dart_ObjectIsType(null, otherType, &is_instance);
   EXPECT_VALID(result);
   EXPECT(!is_instance);
 
@@ -5968,9 +6213,9 @@
   EXPECT(Dart_IsLibrary(lib));
 
   // Call a dynamic function on OldClass.
-  Dart_Handle cls = Dart_GetClass(lib, NewString("OldClass"));
-  EXPECT_VALID(cls);
-  Dart_Handle recv = Dart_New(cls, Dart_Null(), 0, NULL);
+  Dart_Handle type = Dart_GetType(lib, NewString("OldClass"), 0, NULL);
+  EXPECT_VALID(type);
+  Dart_Handle recv = Dart_New(type, Dart_Null(), 0, NULL);
   Dart_Handle result = Dart_Invoke(recv, NewString("foo"), 0, NULL);
   EXPECT_VALID(result);
   EXPECT(Dart_IsString(result));
@@ -5984,9 +6229,9 @@
   EXPECT_VALID(Dart_LoadSource(lib, url, source));
 
   // Call a dynamic function on NewClass in the updated library.
-  cls = Dart_GetClass(lib, NewString("NewClass"));
-  EXPECT_VALID(cls);
-  recv = Dart_New(cls, Dart_Null(), 0, NULL);
+  type = Dart_GetType(lib, NewString("NewClass"), 0, NULL);
+  EXPECT_VALID(type);
+  recv = Dart_New(type, Dart_Null(), 0, NULL);
   result = Dart_Invoke(recv, NewString("bar"), 0, NULL);
   EXPECT_VALID(result);
   EXPECT(Dart_IsString(result));
@@ -6233,8 +6478,8 @@
   Dart_Handle lib = Dart_LoadScript(url, source, 0, 0);
   EXPECT_VALID(lib);
   EXPECT(Dart_IsLibrary(lib));
-  Dart_Handle cls = Dart_GetClass(lib, NewString("Test"));
-  EXPECT_VALID(cls);
+  Dart_Handle type = Dart_GetType(lib, NewString("Test"), 0, NULL);
+  EXPECT_VALID(type);
 
   result = Dart_SetNativeResolver(Dart_Null(), &MyNativeResolver1);
   EXPECT(Dart_IsError(result));
@@ -6256,7 +6501,7 @@
   EXPECT_VALID(result);
 
   // Call a function and make sure native resolution works.
-  result = Dart_Invoke(cls, NewString("foo"), 0, NULL);
+  result = Dart_Invoke(type, NewString("foo"), 0, NULL);
   EXPECT_VALID(result);
   EXPECT(Dart_IsInteger(result));
   int64_t value = 0;
@@ -6268,7 +6513,7 @@
   EXPECT_VALID(result);
 
   // 'foo' has already been resolved so gets the old value.
-  result = Dart_Invoke(cls, NewString("foo"), 0, NULL);
+  result = Dart_Invoke(type, NewString("foo"), 0, NULL);
   EXPECT_VALID(result);
   EXPECT(Dart_IsInteger(result));
   value = 0;
@@ -6276,7 +6521,7 @@
   EXPECT_EQ(654321, value);
 
   // 'bar' has not yet been resolved so gets the new value.
-  result = Dart_Invoke(cls, NewString("bar"), 0, NULL);
+  result = Dart_Invoke(type, NewString("bar"), 0, NULL);
   EXPECT_VALID(result);
   EXPECT(Dart_IsInteger(result));
   value = 0;
@@ -6287,7 +6532,7 @@
   result = Dart_SetNativeResolver(lib, NULL);
   EXPECT_VALID(result);
 
-  EXPECT_ERROR(Dart_Invoke(cls, NewString("baz"), 0, NULL),
+  EXPECT_ERROR(Dart_Invoke(type, NewString("baz"), 0, NULL),
                "native function 'SomeNativeFunction3' cannot be found");
 }
 
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 3d77b54..561aea6 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -236,7 +236,7 @@
     descriptor.SetAt(insert_index + kPositionOffset, pos);
   }
   // Set terminating null.
-  descriptor.SetAt(descriptor_len - 1, Object::Handle());
+  descriptor.SetAt(descriptor_len - 1, Object::null_object());
 
   // Share the immutable descriptor when possible by canonicalizing it.
   descriptor.MakeImmutable();
@@ -271,7 +271,7 @@
   descriptor.SetAt(kPositionalCountIndex, arg_count);
 
   // Set terminating null.
-  descriptor.SetAt((descriptor_len - 1), Object::Handle());
+  descriptor.SetAt((descriptor_len - 1), Object::null_object());
 
   // Share the immutable descriptor when possible by canonicalizing it.
   descriptor.MakeImmutable();
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 8b82f4c..c5cb5da 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -585,7 +585,8 @@
 
 static bool IsSafePoint(PcDescriptors::Kind kind) {
   return ((kind == PcDescriptors::kIcCall) ||
-          (kind == PcDescriptors::kFuncCall) ||
+          (kind == PcDescriptors::kOptStaticCall) ||
+          (kind == PcDescriptors::kUnoptStaticCall) ||
           (kind == PcDescriptors::kClosureCall) ||
           (kind == PcDescriptors::kReturn) ||
           (kind == PcDescriptors::kRuntimeCall));
@@ -658,12 +659,12 @@
       const Code& code =
           Code::Handle(Function::Handle(function_).unoptimized_code());
       saved_bytes_.target_address_ =
-          CodePatcher::GetInstanceCallAt(pc_, code, NULL, NULL);
+          CodePatcher::GetInstanceCallAt(pc_, code, NULL);
       CodePatcher::PatchInstanceCallAt(pc_, code,
                                        StubCode::BreakpointDynamicEntryPoint());
       break;
     }
-    case PcDescriptors::kFuncCall: {
+    case PcDescriptors::kUnoptStaticCall: {
       const Code& code =
           Code::Handle(Function::Handle(function_).unoptimized_code());
       saved_bytes_.target_address_ =
@@ -702,7 +703,7 @@
                                        saved_bytes_.target_address_);
       break;
     }
-    case PcDescriptors::kFuncCall:
+    case PcDescriptors::kUnoptStaticCall:
     case PcDescriptors::kClosureCall:
     case PcDescriptors::kRuntimeCall: {
       const Code& code =
@@ -1178,6 +1179,7 @@
     MakeCodeBreakpointsAt(closure, breakpoint_pos, source_bpt);
   }
   source_bpt->Enable();
+  SignalBpResolved(source_bpt);
   return source_bpt;
 }
 
@@ -1494,7 +1496,8 @@
   if ((fkind == RawFunction::kImplicitGetter) ||
       (fkind == RawFunction::kImplicitSetter) ||
       (fkind == RawFunction::kConstImplicitGetter) ||
-      (fkind == RawFunction::kMethodExtractor)) {
+      (fkind == RawFunction::kMethodExtractor) ||
+      (fkind == RawFunction::kNoSuchMethodDispatcher)) {
     return false;
   }
   const Class& cls = Class::Handle(func.Owner());
@@ -1564,30 +1567,29 @@
     if (bpt->breakpoint_kind_ == PcDescriptors::kIcCall) {
       func_to_instrument = bpt->function();
       ICData& ic_data = ICData::Handle();
-      Array& descriptor = Array::Handle();
       const Code& code =
           Code::Handle(Function::Handle(bpt->function_).unoptimized_code());
-      CodePatcher::GetInstanceCallAt(bpt->pc_, code, &ic_data, &descriptor);
-      ArgumentsDescriptor arg_descriptor(descriptor);
+      CodePatcher::GetInstanceCallAt(bpt->pc_, code, &ic_data);
+      ArgumentsDescriptor
+          args_descriptor(Array::Handle(ic_data.arguments_descriptor()));
       ActivationFrame* top_frame = stack_trace->ActivationFrameAt(0);
-      intptr_t num_args = arg_descriptor.Count();
+      intptr_t num_args = args_descriptor.Count();
       Instance& receiver =
           Instance::Handle(top_frame->GetInstanceCallReceiver(num_args));
       Code& target_code =
-          Code::Handle(ResolveCompileInstanceCallTarget(receiver,
-                                                        ic_data,
-                                                        descriptor));
+          Code::Handle(ResolveCompileInstanceCallTarget(receiver, ic_data));
       if (!target_code.IsNull()) {
         Function& callee = Function::Handle(target_code.function());
         if (IsDebuggable(callee)) {
           func_to_instrument = callee.raw();
         }
       }
-    } else if (bpt->breakpoint_kind_ == PcDescriptors::kFuncCall) {
+    } else if (bpt->breakpoint_kind_ == PcDescriptors::kUnoptStaticCall) {
       func_to_instrument = bpt->function();
       const Code& code = Code::Handle(func_to_instrument.CurrentCode());
-      const Function& callee =
-          Function::Handle(code.GetStaticCallTargetFunctionAt(bpt->pc_));
+      ASSERT(!code.is_optimized());
+      const Function& callee = Function::Handle(
+          CodePatcher::GetUnoptimizedStaticCallAt(bpt->pc_, code, NULL));
       ASSERT(!callee.IsNull());
       if (IsDebuggable(callee)) {
         func_to_instrument = callee.raw();
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index d194c3c..9d22b64 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -280,7 +280,7 @@
       // If the deoptimization happened at an IC call, update the IC data
       // to avoid repeated deoptimization at the same site next time around.
       ICData& ic_data = ICData::Handle();
-      CodePatcher::GetInstanceCallAt(pc, code, &ic_data, NULL);
+      CodePatcher::GetInstanceCallAt(pc, code, &ic_data);
       if (!ic_data.IsNull()) {
         ic_data.set_deopt_reason(deopt_context->deopt_reason());
       }
diff --git a/runtime/vm/find_code_object_test.cc b/runtime/vm/find_code_object_test.cc
index 3200439..ddef528 100644
--- a/runtime/vm/find_code_object_test.cc
+++ b/runtime/vm/find_code_object_test.cc
@@ -16,13 +16,8 @@
 TEST_CASE(FindCodeObject) {
 #if defined(TARGET_ARCH_IA32)
   const int kLoopCount = 50000;
-#elif defined(TARGET_ARCH_X64)
-  const int kLoopCount = 25000;
-#elif defined(TARGET_ARCH_MIPS)
-  // TODO(zra): Increase after we implement far branches on MIPS.
-  const int kLoopCount = 1818;
 #else
-  const int kLoopCount = 20000;
+  const int kLoopCount = 25000;
 #endif
   const int kScriptSize = 512 * KB;
   const int kNumFunctions = 1024;
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 5963f70..1003af0 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -955,11 +955,9 @@
 // Find the natural loop for the back edge m->n and attach loop information
 // to block n (loop header). The algorithm is described in "Advanced Compiler
 // Design & Implementation" (Muchnick) p192.
-static void FindLoop(BlockEntryInstr* m,
-                     BlockEntryInstr* n,
-                     intptr_t num_blocks) {
+void FlowGraph::FindLoop(BlockEntryInstr* m, BlockEntryInstr* n) {
   GrowableArray<BlockEntryInstr*> stack;
-  BitVector* loop = new BitVector(num_blocks);
+  BitVector* loop = new BitVector(preorder_.length());
 
   loop->Add(n->preorder_number());
   if (n != m) {
@@ -980,7 +978,7 @@
   n->set_loop_info(loop);
   if (FLAG_trace_optimization) {
     for (BitVector::Iterator it(loop); !it.Done(); it.Advance()) {
-      OS::Print("  B%"Pd"\n", it.Current());
+      OS::Print("  B%"Pd"\n", preorder_[it.Current()]->block_id());
     }
   }
 }
@@ -1001,7 +999,7 @@
           OS::Print("Back edge B%"Pd" -> B%"Pd"\n", pred->block_id(),
                     block->block_id());
         }
-        FindLoop(pred, block, preorder_.length());
+        FindLoop(pred, block);
         loop_headers->Add(block);
       }
     }
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index 8ed08c8..615cef1 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -218,6 +218,11 @@
   void ReplacePredecessor(BlockEntryInstr* old_block,
                           BlockEntryInstr* new_block);
 
+  // Find the natural loop for the back edge m->n and attach loop
+  // information to block n (loop header). The algorithm is described in
+  // "Advanced Compiler Design & Implementation" (Muchnick) p192.
+  void FindLoop(BlockEntryInstr* m, BlockEntryInstr* n);
+
   // Finds natural loops in the flow graph and attaches a list of loop
   // body blocks for each loop header.
   ZoneGrowableArray<BlockEntryInstr*>* ComputeLoops();
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index d878f8d..c63b362 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -60,6 +60,12 @@
 }
 
 
+static intptr_t NextInstructionPos(intptr_t pos) {
+  ASSERT(IsInstructionStartPosition(pos));
+  return pos + 2;
+}
+
+
 FlowGraphAllocator::FlowGraphAllocator(const FlowGraph& flow_graph)
   : flow_graph_(flow_graph),
     reaching_defs_(flow_graph),
@@ -512,6 +518,16 @@
         range->DefineAt(catch_entry->start_pos());  // Defined at block entry.
         ProcessInitialDefinition(defn, range, catch_entry);
       }
+      // Block the two registers used by CatchEntryInstr from the block start to
+      // until the end of the instruction so that they are preserved.
+      ASSERT(catch_entry->next()->IsCatchEntry());
+      intptr_t start = catch_entry->start_pos();
+      BlockLocation(Location::RegisterLocation(kExceptionObjectReg),
+                    start,
+                    ToInstructionEnd(NextInstructionPos(start)));
+      BlockLocation(Location::RegisterLocation(kStackTraceObjectReg),
+                    start,
+                    ToInstructionEnd(NextInstructionPos(start)));
     }
   }
 
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index ed23d28..36088d9 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -59,6 +59,7 @@
     context_level_(0),
     last_used_try_index_(CatchClauseNode::kInvalidTryIndex),
     try_index_(CatchClauseNode::kInvalidTryIndex),
+    loop_depth_(0),
     graph_entry_(NULL),
     args_pushed_(0),
     osr_id_(osr_id) { }
@@ -499,7 +500,7 @@
     JoinEntryInstr* join =
         new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
     CheckStackOverflowInstr* check =
-        new CheckStackOverflowInstr(token_pos, true);
+        new CheckStackOverflowInstr(token_pos, owner()->loop_depth());
     join->LinkTo(check);
     check->LinkTo(test_fragment.entry());
     Goto(join);
@@ -978,7 +979,7 @@
                                                   name,
                                                   node->kind(),
                                                   arguments,
-                                                  Array::ZoneHandle(),
+                                                  Object::null_array(),
                                                   2,
                                                   owner()->ic_data_array());
   ReturnDefinition(call);
@@ -1222,7 +1223,7 @@
       PrivateCoreLibName(Symbols::_instanceOf()),
       node->kind(),
       arguments,
-      Array::ZoneHandle(),  // No argument names.
+      Object::null_array(),  // No argument names.
       kNumArgsChecked,
       owner()->ic_data_array());
   ReturnDefinition(call);
@@ -1292,7 +1293,7 @@
         PrivateCoreLibName(Symbols::_as()),
         node->kind(),
         arguments,
-        Array::ZoneHandle(),  // No argument names.
+        Object::null_array(),  // No argument names.
         kNumArgsChecked,
         owner()->ic_data_array());
     ReturnDefinition(call);
@@ -1406,7 +1407,7 @@
                                 Symbols::New(Token::Str(node->kind()))),
                             node->kind(),
                             arguments,
-                            Array::ZoneHandle(),
+                            Object::null_array(),
                             1,
                             owner()->ic_data_array());
   ReturnDefinition(call);
@@ -1601,6 +1602,7 @@
 // f) loop-exit-target
 // g) break-join (optional)
 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) {
+  owner()->IncrementLoopDepth();
   TestGraphVisitor for_test(owner(),
                             temp_index(),
                             node->condition()->token_pos());
@@ -1624,6 +1626,7 @@
     Goto(join);
     exit_ = join;
   }
+  owner()->DecrementLoopDepth();
 }
 
 
@@ -1636,6 +1639,7 @@
 // f) loop-exit-target
 // g) break-join
 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
+  owner()->IncrementLoopDepth();
   // Traverse body first in order to generate continue and break labels.
   EffectGraphVisitor for_body(owner(), temp_index());
   node->body()->Visit(&for_body);
@@ -1660,7 +1664,7 @@
                                 owner()->try_index());
     }
     CheckStackOverflowInstr* check =
-        new CheckStackOverflowInstr(node->token_pos(), true);
+        new CheckStackOverflowInstr(node->token_pos(), owner()->loop_depth());
     join->LinkTo(check);
     check->LinkTo(for_test.entry());
     if (body_exit != NULL) {
@@ -1676,6 +1680,7 @@
     for_test.IfFalseGoto(join);
     exit_ = join;
   }
+  owner()->DecrementLoopDepth();
 }
 
 
@@ -1697,6 +1702,7 @@
   Append(for_initializer);
   ASSERT(is_open());
 
+  owner()->IncrementLoopDepth();
   // Compose body to set any jump labels.
   EffectGraphVisitor for_body(owner(), temp_index());
   node->body()->Visit(&for_body);
@@ -1719,7 +1725,8 @@
     }
     Goto(loop_entry);
     exit_ = loop_entry;
-    AddInstruction(new CheckStackOverflowInstr(node->token_pos(), true));
+    AddInstruction(
+        new CheckStackOverflowInstr(node->token_pos(), owner()->loop_depth()));
   }
 
   if (node->condition() == NULL) {
@@ -1743,6 +1750,7 @@
       exit_ = node->label()->join_for_break();
     }
   }
+  owner()->DecrementLoopDepth();
 }
 
 
@@ -2106,7 +2114,8 @@
       new StaticCallInstr(node->token_pos(),
                           node->function(),
                           node->arguments()->names(),
-                          arguments);
+                          arguments,
+                          owner()->ic_data_array());
   if (node->function().is_native()) {
     const intptr_t result_cid = GetResultCidOfNative(node->function());
     call->set_result_cid(result_cid);
@@ -2216,7 +2225,8 @@
   Do(new StaticCallInstr(node->token_pos(),
                          node->constructor(),
                          node->arguments()->names(),
-                         arguments));
+                         arguments,
+                         owner()->ic_data_array()));
 }
 
 
@@ -2284,7 +2294,8 @@
         new StaticCallInstr(node->token_pos(),
                             node->constructor(),
                             node->arguments()->names(),
-                            arguments);
+                            arguments,
+                            owner()->ic_data_array());
     const intptr_t result_cid = GetResultCidOfListFactory(node);
     if (result_cid != kDynamicCid) {
       call->set_result_cid(result_cid);
@@ -2512,7 +2523,7 @@
       node->token_pos(),
       name,
       Token::kGET,
-      arguments, Array::ZoneHandle(),
+      arguments, Object::null_array(),
       1,
       owner()->ic_data_array());
   ReturnDefinition(call);
@@ -2552,7 +2563,7 @@
                                                   name,
                                                   Token::kSET,
                                                   arguments,
-                                                  Array::ZoneHandle(),
+                                                  Object::null_array(),
                                                   2,  // Checked arg count.
                                                   owner()->ic_data_array());
   ReturnDefinition(call);
@@ -2569,7 +2580,7 @@
                            name,
                            Token::kSET,
                            arguments,
-                           Array::ZoneHandle(),
+                           Object::null_array(),
                            2,  // Checked argument count.
                            owner()->ic_data_array()));
   ReturnDefinition(BuildLoadExprTemp());
@@ -2638,8 +2649,9 @@
   ASSERT(!getter_function.IsNull());
   StaticCallInstr* call = new StaticCallInstr(node->token_pos(),
                                               getter_function,
-                                              Array::ZoneHandle(),  // No names.
-                                              arguments);
+                                              Object::null_array(),  // No names
+                                              arguments,
+                                              owner()->ic_data_array());
   ReturnDefinition(call);
 }
 
@@ -2705,8 +2717,9 @@
 
     call = new StaticCallInstr(node->token_pos(),
                                setter_function,
-                               Array::ZoneHandle(),  // No names.
-                               arguments);
+                               Object::null_array(),  // No names.
+                               arguments,
+                               owner()->ic_data_array());
   }
   if (result_is_needed) {
     Do(call);
@@ -2926,8 +2939,9 @@
     // Generate static call to super operator.
     StaticCallInstr* load = new StaticCallInstr(node->token_pos(),
                                                 *super_function,
-                                                Array::ZoneHandle(),
-                                                arguments);
+                                                Object::null_array(),
+                                                arguments,
+                                                owner()->ic_data_array());
     ReturnDefinition(load);
   } else {
     // Generate dynamic call to index operator.
@@ -2936,7 +2950,7 @@
                                                     Symbols::IndexToken(),
                                                     Token::kINDEX,
                                                     arguments,
-                                                    Array::ZoneHandle(),
+                                                    Object::null_array(),
                                                     checked_argument_count,
                                                     owner()->ic_data_array());
     ReturnDefinition(load);
@@ -3005,8 +3019,9 @@
     StaticCallInstr* store =
         new StaticCallInstr(node->token_pos(),
                             *super_function,
-                            Array::ZoneHandle(),
-                            arguments);
+                            Object::null_array(),
+                            arguments,
+                            owner()->ic_data_array());
     if (result_is_needed) {
       Do(store);
       return BuildLoadExprTemp();
@@ -3023,7 +3038,7 @@
                               name,
                               Token::kASSIGN_INDEX,
                               arguments,
-                              Array::ZoneHandle(),
+                              Object::null_array(),
                               checked_argument_count,
                               owner()->ic_data_array());
     if (result_is_needed) {
@@ -3317,8 +3332,9 @@
   BuildPushArguments(*args, push_arguments);
   return new StaticCallInstr(args_pos,
                              no_such_method_func,
-                             Array::ZoneHandle(),
-                             push_arguments);
+                             Object::null_array(),
+                             push_arguments,
+                             owner()->ic_data_array());
 }
 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError(
     intptr_t token_pos,
@@ -3368,13 +3384,14 @@
       Resolver::ResolveStatic(cls,
                               PrivateCoreLibName(Symbols::ThrowNew()),
                               arguments->length(),
-                              Array::ZoneHandle(),
+                              Object::null_array(),
                               Resolver::kIsQualified));
   ASSERT(!func.IsNull());
   return new StaticCallInstr(token_pos,
                              func,
-                             Array::ZoneHandle(),  // No names.
-                             arguments);
+                             Object::null_array(),  // No names.
+                             arguments,
+                             owner()->ic_data_array());
 }
 
 
@@ -3458,7 +3475,7 @@
   EffectGraphVisitor for_effect(this, 0);
   // This check may be deleted if the generated code is leaf.
   CheckStackOverflowInstr* check =
-      new CheckStackOverflowInstr(function.token_pos(), false);
+      new CheckStackOverflowInstr(function.token_pos(), 0);
   // If we are inlining don't actually attach the stack check. We must still
   // create the stack check in order to allocate a deopt id.
   if (!IsInlining()) for_effect.AddInstruction(check);
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 2ae1401..3afcb09 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -120,6 +120,10 @@
   void set_context_level(intptr_t value) { context_level_ = value; }
   intptr_t context_level() const { return context_level_; }
 
+  void IncrementLoopDepth() { ++loop_depth_; }
+  void DecrementLoopDepth() { --loop_depth_; }
+  intptr_t loop_depth() const { return loop_depth_; }
+
   // Each try in this function gets its own try index.
   intptr_t AllocateTryIndex() { return ++last_used_try_index_; }
 
@@ -169,6 +173,7 @@
   intptr_t context_level_;
   intptr_t last_used_try_index_;
   intptr_t try_index_;
+  intptr_t loop_depth_;
   GraphEntryInstr* graph_entry_;
 
   // Outgoing argument stack height.
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 07cc65a..e7f063c 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -30,6 +30,7 @@
 DECLARE_FLAG(bool, report_usage_count);
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(bool, use_cha);
+DECLARE_FLAG(bool, use_osr);
 
 
 // Assign locations to incoming arguments, i.e., values pushed above spill slots
@@ -164,6 +165,11 @@
 }
 
 
+bool FlowGraphCompiler::CanOSRFunction() const {
+  return FLAG_use_osr & CanOptimizeFunction() && !is_optimizing();
+}
+
+
 static bool IsEmptyBlock(BlockEntryInstr* block) {
   return !block->HasParallelMove() &&
          block->next()->IsGoto() &&
@@ -461,7 +467,7 @@
 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) {
   if (stackmap_table_builder_ == NULL) {
     // The unoptimizing compiler has no stack maps.
-    code.set_stackmaps(Array::Handle());
+    code.set_stackmaps(Object::null_array());
   } else {
     // Finalize the stack map array and add it to the code object.
     ASSERT(is_optimizing());
@@ -540,9 +546,6 @@
     const ICData& ic_data) {
   ASSERT(!ic_data.IsNull());
   ASSERT(FLAG_propagate_ic_data || (ic_data.NumberOfChecks() == 0));
-  const Array& arguments_descriptor =
-      Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
-                                                 argument_names));
   uword label_address = 0;
   if (is_optimizing() && (ic_data.NumberOfChecks() == 0)) {
     if (ic_data.is_closure_call()) {
@@ -551,8 +554,7 @@
       ExternalLabel target_label("InlineCache", label_address);
       EmitInstanceCall(&target_label,
                        ICData::ZoneHandle(ic_data.AsUnaryClassChecks()),
-                       arguments_descriptor, argument_count,
-                       deopt_id, token_pos, locs);
+                       argument_count, deopt_id, token_pos, locs);
       return;
     }
     // Emit IC call that will count and thus may need reoptimization at
@@ -575,13 +577,13 @@
         UNIMPLEMENTED();
     }
     ExternalLabel target_label("InlineCache", label_address);
-    EmitOptimizedInstanceCall(&target_label, ic_data, arguments_descriptor,
+    EmitOptimizedInstanceCall(&target_label, ic_data,
                               argument_count, deopt_id, token_pos, locs);
     return;
   }
 
   if (is_optimizing()) {
-    EmitMegamorphicInstanceCall(ic_data, arguments_descriptor, argument_count,
+    EmitMegamorphicInstanceCall(ic_data, argument_count,
                                 deopt_id, token_pos, locs);
     return;
   }
@@ -600,7 +602,7 @@
       UNIMPLEMENTED();
   }
   ExternalLabel target_label("InlineCache", label_address);
-  EmitInstanceCall(&target_label, ic_data, arguments_descriptor, argument_count,
+  EmitInstanceCall(&target_label, ic_data, argument_count,
                    deopt_id, token_pos, locs);
 }
 
@@ -614,8 +616,13 @@
   const Array& arguments_descriptor =
       Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
                                                  argument_names));
-  EmitStaticCall(function, arguments_descriptor, argument_count,
-                 deopt_id, token_pos, locs);
+  if (is_optimizing()) {
+    EmitOptimizedStaticCall(function, arguments_descriptor, argument_count,
+                            deopt_id, token_pos, locs);
+  } else {
+    EmitUnoptimizedStaticCall(function, arguments_descriptor, argument_count,
+                              deopt_id, token_pos, locs);
+  }
 }
 
 
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 6dbcaa4..4759b25 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -258,6 +258,7 @@
   }
   static bool CanOptimize();
   bool CanOptimizeFunction() const;
+  bool CanOSRFunction() const;
   bool is_optimizing() const { return is_optimizing_; }
 
   const GrowableArray<BlockInfo*>& block_info() const { return block_info_; }
@@ -336,7 +337,6 @@
 
   void EmitOptimizedInstanceCall(ExternalLabel* target_label,
                                  const ICData& ic_data,
-                                 const Array& arguments_descriptor,
                                  intptr_t argument_count,
                                  intptr_t deopt_id,
                                  intptr_t token_pos,
@@ -344,14 +344,12 @@
 
   void EmitInstanceCall(ExternalLabel* target_label,
                         const ICData& ic_data,
-                        const Array& arguments_descriptor,
                         intptr_t argument_count,
                         intptr_t deopt_id,
                         intptr_t token_pos,
                         LocationSummary* locs);
 
   void EmitMegamorphicInstanceCall(const ICData& ic_data,
-                                   const Array& arguments_descriptor,
                                    intptr_t argument_count,
                                    intptr_t deopt_id,
                                    intptr_t token_pos,
@@ -481,12 +479,19 @@
   // Emit code to load a Value into register 'dst'.
   void LoadValue(Register dst, Value* value);
 
-  void EmitStaticCall(const Function& function,
-                      const Array& arguments_descriptor,
-                      intptr_t argument_count,
-                      intptr_t deopt_id,
-                      intptr_t token_pos,
-                      LocationSummary* locs);
+  void EmitOptimizedStaticCall(const Function& function,
+                               const Array& arguments_descriptor,
+                               intptr_t argument_count,
+                               intptr_t deopt_id,
+                               intptr_t token_pos,
+                               LocationSummary* locs);
+
+  void EmitUnoptimizedStaticCall(const Function& function,
+                                 const Array& arguments_descriptor,
+                                 intptr_t argument_count,
+                                 intptr_t deopt_id,
+                                 intptr_t token_pos,
+                                 LocationSummary* locs);
 
   // Type checking helper methods.
   void CheckClassIds(Register class_id_reg,
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index eab7bc6..ce260cf 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -910,7 +910,8 @@
       function.IsClosureFunction() ? Symbols::Call().raw() : function.name());
   const int kNumArgsChecked = 1;
   const ICData& ic_data = ICData::ZoneHandle(
-      ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked));
+      ICData::New(function, name, Object::null_array(),
+                  Isolate::kNoDeoptId, kNumArgsChecked));
   __ LoadObject(R5, ic_data);
   // FP - 4 : saved PP, object pool pointer of caller.
   // FP + 0 : previous frame pointer.
@@ -1067,7 +1068,8 @@
     ASSERT(!parsed_function().function().HasOptionalParameters());
     const bool check_arguments = true;
 #else
-    const bool check_arguments = function.IsClosureFunction();
+    const bool check_arguments =
+        function.IsClosureFunction() || function.IsNoSuchMethodDispatcher();
 #endif
     if (check_arguments) {
       __ Comment("Check argument count");
@@ -1081,7 +1083,7 @@
       __ cmp(R0, ShifterOperand(R1));
       __ b(&correct_num_arguments, EQ);
       __ Bind(&wrong_num_arguments);
-      if (function.IsClosureFunction()) {
+      if (function.IsClosureFunction() || function.IsNoSuchMethodDispatcher()) {
         if (StackSize() != 0) {
           // We need to unwind the space we reserved for locals and copied
           // parameters. The NoSuchMethodFunction stub does not expect to see
@@ -1092,10 +1094,15 @@
         // dropped the spill slots.
         BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
 
-        // Invoke noSuchMethod function passing "call" as the function name.
+        // Invoke noSuchMethod function passing the original function name.
+        // For closure functions, use "call" as the original name.
+        const String& name =
+            String::Handle(function.IsClosureFunction()
+                             ? Symbols::Call().raw()
+                             : function.name());
         const int kNumArgsChecked = 1;
         const ICData& ic_data = ICData::ZoneHandle(
-            ICData::New(function, Symbols::Call(),
+            ICData::New(function, name, Object::null_array(),
                         Isolate::kNoDeoptId, kNumArgsChecked));
         __ LoadObject(R5, ic_data);
         // FP - 4 : saved PP, object pool pointer of caller.
@@ -1238,7 +1245,6 @@
 void FlowGraphCompiler::EmitOptimizedInstanceCall(
     ExternalLabel* target_label,
     const ICData& ic_data,
-    const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
@@ -1249,8 +1255,8 @@
   // top-level function (parsed_function().function()) which could be
   // reoptimized and which counter needs to be incremented.
   // Pass the function explicitly, it is used in IC stub.
+
   __ LoadObject(R6, parsed_function().function());
-  __ LoadObject(R4, arguments_descriptor);
   __ LoadObject(R5, ic_data);
   GenerateDartCall(deopt_id,
                    token_pos,
@@ -1263,12 +1269,10 @@
 
 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
                                          const ICData& ic_data,
-                                         const Array& arguments_descriptor,
                                          intptr_t argument_count,
                                          intptr_t deopt_id,
                                          intptr_t token_pos,
                                          LocationSummary* locs) {
-  __ LoadObject(R4, arguments_descriptor);
   __ LoadObject(R5, ic_data);
   GenerateDartCall(deopt_id,
                    token_pos,
@@ -1281,13 +1285,15 @@
 
 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
     const ICData& ic_data,
-    const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
     LocationSummary* locs) {
   MegamorphicCacheTable* table = Isolate::Current()->megamorphic_cache_table();
   const String& name = String::Handle(ic_data.target_name());
+  const Array& arguments_descriptor =
+      Array::ZoneHandle(ic_data.arguments_descriptor());
+  ASSERT(!arguments_descriptor.IsNull());
   const MegamorphicCache& cache =
       MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
   Label not_smi, load_cache;
@@ -1348,25 +1354,50 @@
 }
 
 
-void FlowGraphCompiler::EmitStaticCall(const Function& function,
-                                       const Array& arguments_descriptor,
-                                       intptr_t argument_count,
-                                       intptr_t deopt_id,
-                                       intptr_t token_pos,
-                                       LocationSummary* locs) {
+void FlowGraphCompiler::EmitOptimizedStaticCall(
+    const Function& function,
+    const Array& arguments_descriptor,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
   __ LoadObject(R4, arguments_descriptor);
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
   GenerateDartCall(deopt_id,
                    token_pos,
                    &StubCode::CallStaticFunctionLabel(),
-                   PcDescriptors::kFuncCall,
+                   PcDescriptors::kOptStaticCall,
                    locs);
   AddStaticCallTarget(function);
   __ Drop(argument_count);
 }
 
 
+void FlowGraphCompiler::EmitUnoptimizedStaticCall(
+    const Function& target_function,
+    const Array& arguments_descriptor,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  const ICData& ic_data = ICData::ZoneHandle(
+      ICData::New(parsed_function().function(),  // Caller function.
+                  String::Handle(target_function.name()),
+                  arguments_descriptor,
+                  deopt_id,
+                  0));  // No arguments checked.
+  ic_data.AddTarget(target_function);
+  __ LoadObject(R5, ic_data);
+  GenerateDartCall(deopt_id,
+                   token_pos,
+                   &StubCode::UnoptimizedStaticCallLabel(),
+                   PcDescriptors::kUnoptStaticCall,
+                   locs);
+  __ Drop(argument_count);
+}
+
+
 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
                                                     const Object& obj,
                                                     bool needs_number_check,
@@ -1495,6 +1526,7 @@
                                         intptr_t deopt_id,
                                         intptr_t token_index,
                                         LocationSummary* locs) {
+  ASSERT(is_optimizing());
   ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
   Label match_found;
   const intptr_t len = ic_data.NumberOfChecks();
@@ -1520,7 +1552,7 @@
     GenerateDartCall(deopt_id,
                      token_index,
                      &StubCode::CallStaticFunctionLabel(),
-                     PcDescriptors::kFuncCall,
+                     PcDescriptors::kOptStaticCall,
                      locs);
     const Function& function = *sorted[i].target;
     AddStaticCallTarget(function);
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index fe154c7..6504aa6 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -1008,7 +1008,8 @@
       function.IsClosureFunction() ? Symbols::Call().raw() : function.name());
   const int kNumArgsChecked = 1;
   const ICData& ic_data = ICData::ZoneHandle(
-      ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked));
+      ICData::New(function, name, Object::null_array(),
+                  Isolate::kNoDeoptId, kNumArgsChecked));
   __ LoadObject(ECX, ic_data);
   // EBP - 4 : PC marker, allows easy identification of RawInstruction obj.
   // EBP : points to previous frame pointer.
@@ -1149,7 +1150,8 @@
     const bool check_arguments = !flow_graph().IsCompiledForOsr();
 #else
     const bool check_arguments =
-        function.IsClosureFunction() && !flow_graph().IsCompiledForOsr();
+        (function.IsClosureFunction() || function.IsNoSuchMethodDispatcher()) &&
+        !flow_graph().IsCompiledForOsr();
 #endif
     if (check_arguments) {
       __ Comment("Check argument count");
@@ -1164,7 +1166,7 @@
       __ j(EQUAL, &correct_num_arguments, Assembler::kNearJump);
 
       __ Bind(&wrong_num_arguments);
-      if (function.IsClosureFunction()) {
+      if (function.IsClosureFunction() || function.IsNoSuchMethodDispatcher()) {
         if (StackSize() != 0) {
           // We need to unwind the space we reserved for locals and copied
           // parameters. The NoSuchMethodFunction stub does not expect to see
@@ -1175,10 +1177,15 @@
         // dropped the spill slots.
         BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
 
-        // Invoke noSuchMethod function passing "call" as the function name.
+        // Invoke noSuchMethod function passing the original function name.
+        // For closure functions, use "call" as the original name.
+        const String& name =
+            String::Handle(function.IsClosureFunction()
+                             ? Symbols::Call().raw()
+                             : function.name());
         const int kNumArgsChecked = 1;
         const ICData& ic_data = ICData::ZoneHandle(
-            ICData::New(function, Symbols::Call(),
+            ICData::New(function, name, Object::null_array(),
                         Isolate::kNoDeoptId, kNumArgsChecked));
         __ LoadObject(ECX, ic_data);
         // EBP - 4 : PC marker, for easy identification of RawInstruction obj.
@@ -1320,7 +1327,6 @@
 void FlowGraphCompiler::EmitOptimizedInstanceCall(
     ExternalLabel* target_label,
     const ICData& ic_data,
-    const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
@@ -1333,7 +1339,6 @@
   // Pass the function explicitly, it is used in IC stub.
   __ LoadObject(EDI, parsed_function().function());
   __ LoadObject(ECX, ic_data);
-  __ LoadObject(EDX, arguments_descriptor);
   GenerateDartCall(deopt_id,
                    token_pos,
                    target_label,
@@ -1345,13 +1350,11 @@
 
 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
                                          const ICData& ic_data,
-                                         const Array& arguments_descriptor,
                                          intptr_t argument_count,
                                          intptr_t deopt_id,
                                          intptr_t token_pos,
                                          LocationSummary* locs) {
   __ LoadObject(ECX, ic_data);
-  __ LoadObject(EDX, arguments_descriptor);
   GenerateDartCall(deopt_id,
                    token_pos,
                    target_label,
@@ -1363,13 +1366,15 @@
 
 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
     const ICData& ic_data,
-    const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
     LocationSummary* locs) {
   MegamorphicCacheTable* table = Isolate::Current()->megamorphic_cache_table();
   const String& name = String::Handle(ic_data.target_name());
+  const Array& arguments_descriptor =
+      Array::ZoneHandle(ic_data.arguments_descriptor());
+  ASSERT(!arguments_descriptor.IsNull());
   const MegamorphicCache& cache =
       MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
   Label not_smi, load_cache;
@@ -1428,25 +1433,50 @@
 }
 
 
-void FlowGraphCompiler::EmitStaticCall(const Function& function,
-                                       const Array& arguments_descriptor,
-                                       intptr_t argument_count,
-                                       intptr_t deopt_id,
-                                       intptr_t token_pos,
-                                       LocationSummary* locs) {
+void FlowGraphCompiler::EmitOptimizedStaticCall(
+    const Function& function,
+    const Array& arguments_descriptor,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
   __ LoadObject(EDX, arguments_descriptor);
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
   GenerateDartCall(deopt_id,
                    token_pos,
                    &StubCode::CallStaticFunctionLabel(),
-                   PcDescriptors::kFuncCall,
+                   PcDescriptors::kOptStaticCall,
                    locs);
   AddStaticCallTarget(function);
   __ Drop(argument_count);
 }
 
 
+void FlowGraphCompiler::EmitUnoptimizedStaticCall(
+    const Function& target_function,
+    const Array& arguments_descriptor,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  const ICData& ic_data = ICData::ZoneHandle(
+      ICData::New(parsed_function().function(),  // Caller function.
+                  String::Handle(target_function.name()),
+                  arguments_descriptor,
+                  deopt_id,
+                  0));  // No arguments checked.
+  ic_data.AddTarget(target_function);
+  __ LoadObject(ECX, ic_data);
+  GenerateDartCall(deopt_id,
+                   token_pos,
+                   &StubCode::UnoptimizedStaticCallLabel(),
+                   PcDescriptors::kUnoptStaticCall,
+                   locs);
+  __ Drop(argument_count);
+}
+
+
 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
                                                     const Object& obj,
                                                     bool needs_number_check,
@@ -1592,6 +1622,7 @@
                                         intptr_t deopt_id,
                                         intptr_t token_index,
                                         LocationSummary* locs) {
+  ASSERT(is_optimizing());
   ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
   Label match_found;
   const intptr_t len = ic_data.NumberOfChecks();
@@ -1617,7 +1648,7 @@
     GenerateDartCall(deopt_id,
                      token_index,
                      &StubCode::CallStaticFunctionLabel(),
-                     PcDescriptors::kFuncCall,
+                     PcDescriptors::kOptStaticCall,
                      locs);
     const Function& function = *sorted[i].target;
     AddStaticCallTarget(function);
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index a088cc6..2177423 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -936,7 +936,8 @@
       function.IsClosureFunction() ? Symbols::Call().raw() : function.name());
   const int kNumArgsChecked = 1;
   const ICData& ic_data = ICData::ZoneHandle(
-      ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked));
+      ICData::New(function, name, Object::null_array(),
+                  Isolate::kNoDeoptId, kNumArgsChecked));
   __ LoadObject(S5, ic_data);
   // FP - 4 : saved PP, object pool pointer of caller.
   // FP + 0 : previous frame pointer.
@@ -1116,7 +1117,8 @@
     ASSERT(!parsed_function().function().HasOptionalParameters());
     const bool check_arguments = true;
 #else
-    const bool check_arguments = function.IsClosureFunction();
+    const bool check_arguments =
+        function.IsClosureFunction() || function.IsNoSuchMethodDispatcher();
 #endif
     if (check_arguments) {
       __ TraceSimMsg("Check argument count");
@@ -1131,7 +1133,7 @@
                              ArgumentsDescriptor::positional_count_offset()));
       __ beq(T0, T1, &correct_num_arguments);
       __ Bind(&wrong_num_arguments);
-      if (function.IsClosureFunction()) {
+      if (function.IsClosureFunction() || function.IsNoSuchMethodDispatcher()) {
         if (StackSize() != 0) {
           // We need to unwind the space we reserved for locals and copied
           // parameters. The NoSuchMethodFunction stub does not expect to see
@@ -1142,10 +1144,15 @@
         // dropped the spill slots.
         BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
 
-        // Invoke noSuchMethod function passing "call" as the function name.
+        // Invoke noSuchMethod function passing the original function name.
+        // For closure functions, use "call" as the original name.
+        const String& name =
+            String::Handle(function.IsClosureFunction()
+                             ? Symbols::Call().raw()
+                             : function.name());
         const int kNumArgsChecked = 1;
         const ICData& ic_data = ICData::ZoneHandle(
-            ICData::New(function, Symbols::Call(),
+            ICData::New(function, name, Object::null_array(),
                         Isolate::kNoDeoptId, kNumArgsChecked));
         __ LoadObject(S5, ic_data);
         // FP - 4 : saved PP, object pool pointer of caller.
@@ -1290,7 +1297,6 @@
 void FlowGraphCompiler::EmitOptimizedInstanceCall(
     ExternalLabel* target_label,
     const ICData& ic_data,
-    const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
@@ -1303,7 +1309,6 @@
   // Pass the function explicitly, it is used in IC stub.
   __ TraceSimMsg("OptimizedInstanceCall");
   __ LoadObject(T0, parsed_function().function());
-  __ LoadObject(S4, arguments_descriptor);
   __ LoadObject(S5, ic_data);
   GenerateDartCall(deopt_id,
                    token_pos,
@@ -1316,13 +1321,11 @@
 
 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
                                          const ICData& ic_data,
-                                         const Array& arguments_descriptor,
                                          intptr_t argument_count,
                                          intptr_t deopt_id,
                                          intptr_t token_pos,
                                          LocationSummary* locs) {
   __ TraceSimMsg("InstanceCall");
-  __ LoadObject(S4, arguments_descriptor);
   __ LoadObject(S5, ic_data);
   GenerateDartCall(deopt_id,
                    token_pos,
@@ -1336,13 +1339,15 @@
 
 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
     const ICData& ic_data,
-    const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
     LocationSummary* locs) {
   MegamorphicCacheTable* table = Isolate::Current()->megamorphic_cache_table();
   const String& name = String::Handle(ic_data.target_name());
+  const Array& arguments_descriptor =
+      Array::ZoneHandle(ic_data.arguments_descriptor());
+  ASSERT(!arguments_descriptor.IsNull());
   const MegamorphicCache& cache =
       MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
   Label not_smi, load_cache;
@@ -1404,12 +1409,13 @@
 }
 
 
-void FlowGraphCompiler::EmitStaticCall(const Function& function,
-                                       const Array& arguments_descriptor,
-                                       intptr_t argument_count,
-                                       intptr_t deopt_id,
-                                       intptr_t token_pos,
-                                       LocationSummary* locs) {
+void FlowGraphCompiler::EmitOptimizedStaticCall(
+    const Function& function,
+    const Array& arguments_descriptor,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
   __ TraceSimMsg("StaticCall");
   __ LoadObject(S4, arguments_descriptor);
   // Do not use the code from the function, but let the code be patched so that
@@ -1417,13 +1423,37 @@
   GenerateDartCall(deopt_id,
                    token_pos,
                    &StubCode::CallStaticFunctionLabel(),
-                   PcDescriptors::kFuncCall,
+                   PcDescriptors::kOptStaticCall,
                    locs);
   AddStaticCallTarget(function);
   __ Drop(argument_count);
 }
 
 
+void FlowGraphCompiler::EmitUnoptimizedStaticCall(
+    const Function& target_function,
+    const Array& arguments_descriptor,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  const ICData& ic_data = ICData::ZoneHandle(
+      ICData::New(parsed_function().function(),  // Caller function.
+                  String::Handle(target_function.name()),
+                  arguments_descriptor,
+                  deopt_id,
+                  0));  // No arguments checked.
+  ic_data.AddTarget(target_function);
+  __ LoadObject(S5, ic_data);
+  GenerateDartCall(deopt_id,
+                   token_pos,
+                   &StubCode::UnoptimizedStaticCallLabel(),
+                   PcDescriptors::kUnoptStaticCall,
+                   locs);
+  __ Drop(argument_count);
+}
+
+
 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
                                                     const Object& obj,
                                                     bool needs_number_check,
@@ -1579,6 +1609,7 @@
                                         intptr_t deopt_id,
                                         intptr_t token_index,
                                         LocationSummary* locs) {
+  ASSERT(is_optimizing());
   ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
   Label match_found;
   const intptr_t len = ic_data.NumberOfChecks();
@@ -1605,7 +1636,7 @@
     GenerateDartCall(deopt_id,
                      token_index,
                      &StubCode::CallStaticFunctionLabel(),
-                     PcDescriptors::kFuncCall,
+                     PcDescriptors::kOptStaticCall,
                      locs);
     const Function& function = *sorted[i].target;
     AddStaticCallTarget(function);
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index df39bc48..6190bb1 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -1002,7 +1002,8 @@
       function.IsClosureFunction() ? Symbols::Call().raw() : function.name());
   const int kNumArgsChecked = 1;
   const ICData& ic_data = ICData::ZoneHandle(
-      ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked));
+      ICData::New(function, name, Object::null_array(),
+                  Isolate::kNoDeoptId, kNumArgsChecked));
   __ LoadObject(RBX, ic_data);
   // RBP - 8 : PC marker, allows easy identification of RawInstruction obj.
   // RBP : points to previous frame pointer.
@@ -1144,7 +1145,8 @@
     const bool check_arguments = !flow_graph().IsCompiledForOsr();
 #else
     const bool check_arguments =
-        function.IsClosureFunction() && !flow_graph().IsCompiledForOsr();
+        (function.IsClosureFunction() || function.IsNoSuchMethodDispatcher()) &&
+        !flow_graph().IsCompiledForOsr();
 #endif
     if (check_arguments) {
       __ Comment("Check argument count");
@@ -1159,7 +1161,7 @@
       __ j(EQUAL, &correct_num_arguments, Assembler::kNearJump);
 
       __ Bind(&wrong_num_arguments);
-      if (function.IsClosureFunction()) {
+      if (function.IsClosureFunction() || function.IsNoSuchMethodDispatcher()) {
         if (StackSize() != 0) {
           // We need to unwind the space we reserved for locals and copied
           // parameters. The NoSuchMethodFunction stub does not expect to see
@@ -1170,10 +1172,15 @@
         // dropped the spill slots.
         BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
 
-        // Invoke noSuchMethod function passing "call" as the function name.
+        // Invoke noSuchMethod function passing the original function name.
+        // For closure functions, use "call" as the original name.
+        const String& name =
+            String::Handle(function.IsClosureFunction()
+                             ? Symbols::Call().raw()
+                             : function.name());
         const int kNumArgsChecked = 1;
         const ICData& ic_data = ICData::ZoneHandle(
-            ICData::New(function, Symbols::Call(),
+            ICData::New(function, name, Object::null_array(),
                         Isolate::kNoDeoptId, kNumArgsChecked));
         __ LoadObject(RBX, ic_data);
         // RBP - 8 : PC marker, for easy identification of RawInstruction obj.
@@ -1315,7 +1322,6 @@
 void FlowGraphCompiler::EmitOptimizedInstanceCall(
     ExternalLabel* target_label,
     const ICData& ic_data,
-    const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
@@ -1328,7 +1334,6 @@
   // Pass the function explicitly, it is used in IC stub.
   __ LoadObject(RDI, parsed_function().function());
   __ LoadObject(RBX, ic_data);
-  __ LoadObject(R10, arguments_descriptor);
   GenerateDartCall(deopt_id,
                    token_pos,
                    target_label,
@@ -1340,13 +1345,11 @@
 
 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
                                          const ICData& ic_data,
-                                         const Array& arguments_descriptor,
                                          intptr_t argument_count,
                                          intptr_t deopt_id,
                                          intptr_t token_pos,
                                          LocationSummary* locs) {
   __ LoadObject(RBX, ic_data);
-  __ LoadObject(R10, arguments_descriptor);
   GenerateDartCall(deopt_id,
                    token_pos,
                    target_label,
@@ -1358,13 +1361,15 @@
 
 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
     const ICData& ic_data,
-    const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
     LocationSummary* locs) {
   MegamorphicCacheTable* table = Isolate::Current()->megamorphic_cache_table();
   const String& name = String::Handle(ic_data.target_name());
+  const Array& arguments_descriptor =
+      Array::ZoneHandle(ic_data.arguments_descriptor());
+  ASSERT(!arguments_descriptor.IsNull());
   const MegamorphicCache& cache =
       MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
   Label not_smi, load_cache;
@@ -1423,25 +1428,50 @@
 }
 
 
-void FlowGraphCompiler::EmitStaticCall(const Function& function,
-                                       const Array& arguments_descriptor,
-                                       intptr_t argument_count,
-                                       intptr_t deopt_id,
-                                       intptr_t token_pos,
-                                       LocationSummary* locs) {
+void FlowGraphCompiler::EmitOptimizedStaticCall(
+    const Function& function,
+    const Array& arguments_descriptor,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
   __ LoadObject(R10, arguments_descriptor);
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
   GenerateDartCall(deopt_id,
                    token_pos,
                    &StubCode::CallStaticFunctionLabel(),
-                   PcDescriptors::kFuncCall,
+                   PcDescriptors::kOptStaticCall,
                    locs);
   AddStaticCallTarget(function);
   __ Drop(argument_count);
 }
 
 
+void FlowGraphCompiler::EmitUnoptimizedStaticCall(
+    const Function& target_function,
+    const Array& arguments_descriptor,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  const ICData& ic_data = ICData::ZoneHandle(
+      ICData::New(parsed_function().function(),  // Caller function.
+                  String::Handle(target_function.name()),
+                  arguments_descriptor,
+                  deopt_id,
+                  0));  // No arguments checked.
+  ic_data.AddTarget(target_function);
+  __ LoadObject(RBX, ic_data);
+  GenerateDartCall(deopt_id,
+                   token_pos,
+                   &StubCode::UnoptimizedStaticCallLabel(),
+                   PcDescriptors::kUnoptStaticCall,
+                   locs);
+  __ Drop(argument_count);
+}
+
+
 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
                                                     const Object& obj,
                                                     bool needs_number_check,
@@ -1587,6 +1617,7 @@
                                         intptr_t deopt_id,
                                         intptr_t token_index,
                                         LocationSummary* locs) {
+  ASSERT(is_optimizing());
   ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
   Label match_found;
   const intptr_t len = ic_data.NumberOfChecks();
@@ -1612,7 +1643,7 @@
     GenerateDartCall(deopt_id,
                      token_index,
                      &StubCode::CallStaticFunctionLabel(),
-                     PcDescriptors::kFuncCall,
+                     PcDescriptors::kOptStaticCall,
                      locs);
     const Function& function = *sorted[i].target;
     AddStaticCallTarget(function);
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 6d86710..fe8573a 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -186,12 +186,7 @@
       : FlowGraphVisitor(flow_graph->postorder()),  // We don't use this order.
         static_calls_(),
         closure_calls_(),
-        instance_calls_(),
-        skip_static_call_deopt_ids_() { }
-
-  const GrowableArray<StaticCallInstr*>& static_calls() const {
-    return static_calls_;
-  }
+        instance_calls_() { }
 
   const GrowableArray<ClosureCallInstr*>& closure_calls() const {
     return closure_calls_;
@@ -204,10 +199,21 @@
         : call(call_arg), ratio(0.0) {}
   };
 
+  struct StaticCallInfo {
+    StaticCallInstr* call;
+    double ratio;
+    explicit StaticCallInfo(StaticCallInstr* value)
+        : call(value), ratio(0.0) {}
+  };
+
   const GrowableArray<InstanceCallInfo>& instance_calls() const {
     return instance_calls_;
   }
 
+  const GrowableArray<StaticCallInfo>& static_calls() const {
+    return static_calls_;
+  }
+
   bool HasCalls() const {
     return !(static_calls_.is_empty() &&
              closure_calls_.is_empty() &&
@@ -218,19 +224,52 @@
     static_calls_.Clear();
     closure_calls_.Clear();
     instance_calls_.Clear();
-    skip_static_call_deopt_ids_.Clear();
+  }
+
+  void ComputeCallSiteRatio(intptr_t static_call_start_ix,
+                            intptr_t instance_call_start_ix) {
+    const intptr_t num_static_calls =
+        static_calls_.length() - static_call_start_ix;
+    const intptr_t num_instance_calls =
+        instance_calls_.length() - instance_call_start_ix;
+
+    intptr_t max_count = 0;
+    GrowableArray<intptr_t> instance_call_counts(num_instance_calls);
+    for (intptr_t i = 0; i < num_instance_calls; ++i) {
+      const intptr_t aggregate_count =
+          instance_calls_[i + instance_call_start_ix].
+              call->ic_data().AggregateCount();
+      instance_call_counts.Add(aggregate_count);
+      if (aggregate_count > max_count) max_count = aggregate_count;
+    }
+
+    GrowableArray<intptr_t> static_call_counts(num_static_calls);
+    for (intptr_t i = 0; i < num_static_calls; ++i) {
+      const intptr_t aggregate_count =
+          static_calls_[i + static_call_start_ix].
+              call->ic_data()->AggregateCount();
+      static_call_counts.Add(aggregate_count);
+      if (aggregate_count > max_count) max_count = aggregate_count;
+    }
+
+    // max_count can be 0 if none of the calls was executed.
+    for (intptr_t i = 0; i < num_instance_calls; ++i) {
+      const double ratio = (max_count == 0) ?
+          0.0 : static_cast<double>(instance_call_counts[i]) / max_count;
+      instance_calls_[i + instance_call_start_ix].ratio = ratio;
+    }
+    for (intptr_t i = 0; i < num_static_calls; ++i) {
+      const double ratio = (max_count == 0) ?
+          0.0 : static_cast<double>(static_call_counts[i]) / max_count;
+      static_calls_[i + static_call_start_ix].ratio = ratio;
+    }
   }
 
   void FindCallSites(FlowGraph* graph) {
     ASSERT(graph != NULL);
-    const Function& function = graph->parsed_function().function();
-    ASSERT(function.HasCode());
-    const Code& code = Code::Handle(function.unoptimized_code());
-
-    skip_static_call_deopt_ids_.Clear();
-    code.ExtractUncalledStaticCallDeoptIds(&skip_static_call_deopt_ids_);
 
     const intptr_t instance_call_start_ix = instance_calls_.length();
+    const intptr_t static_call_start_ix = static_calls_.length();
     for (BlockIterator block_it = graph->postorder_iterator();
          !block_it.Done();
          block_it.Advance()) {
@@ -240,24 +279,7 @@
         it.Current()->Accept(this);
       }
     }
-    // Compute instance call site ratio.
-    const intptr_t num_instance_calls =
-        instance_calls_.length() - instance_call_start_ix;
-    intptr_t max_count = 0;
-    GrowableArray<intptr_t> call_counts(num_instance_calls);
-    for (intptr_t i = 0; i < num_instance_calls; ++i) {
-      const intptr_t aggregate_count =
-          instance_calls_[i + instance_call_start_ix].
-              call->ic_data().AggregateCount();
-      call_counts.Add(aggregate_count);
-      if (aggregate_count > max_count) max_count = aggregate_count;
-    }
-
-
-    for (intptr_t i = 0; i < num_instance_calls; ++i) {
-      const double ratio = static_cast<double>(call_counts[i]) / max_count;
-      instance_calls_[i + instance_call_start_ix].ratio = ratio;
-    }
+    ComputeCallSiteRatio(static_call_start_ix, instance_call_start_ix);
   }
 
   void VisitClosureCall(ClosureCallInstr* call) {
@@ -270,21 +292,13 @@
 
   void VisitStaticCall(StaticCallInstr* call) {
     if (!call->function().IsInlineable()) return;
-    const intptr_t call_deopt_id = call->deopt_id();
-    for (intptr_t i = 0; i < skip_static_call_deopt_ids_.length(); i++) {
-      if (call_deopt_id == skip_static_call_deopt_ids_[i]) {
-        // Do not inline this call.
-        return;
-      }
-    }
-    static_calls_.Add(call);
+    static_calls_.Add(StaticCallInfo(call));
   }
 
  private:
-  GrowableArray<StaticCallInstr*> static_calls_;
+  GrowableArray<StaticCallInfo> static_calls_;
   GrowableArray<ClosureCallInstr*> closure_calls_;
   GrowableArray<InstanceCallInfo> instance_calls_;
-  GrowableArray<intptr_t> skip_static_call_deopt_ids_;
 
   DISALLOW_COPY_AND_ASSIGN(CallSites);
 };
@@ -713,11 +727,11 @@
   // if the incoming argument is a non-constant value.
   // TODO(srdjan): Fix inlining of List. factory.
   void InlineStaticCalls() {
-    const GrowableArray<StaticCallInstr*>& calls =
+    const GrowableArray<CallSites::StaticCallInfo>& call_info =
         inlining_call_sites_->static_calls();
-    TRACE_INLINING(OS::Print("  Static Calls (%d)\n", calls.length()));
-    for (intptr_t i = 0; i < calls.length(); ++i) {
-      StaticCallInstr* call = calls[i];
+    TRACE_INLINING(OS::Print("  Static Calls (%d)\n", call_info.length()));
+    for (intptr_t call_idx = 0; call_idx < call_info.length(); ++call_idx) {
+      StaticCallInstr* call = call_info[call_idx].call;
       if (call->function().name() == Symbols::ListFactory().raw()) {
         // Inline only if no arguments or a constant was passed.
         ASSERT(call->function().NumImplicitParameters() == 1);
@@ -730,6 +744,15 @@
           continue;
         }
       }
+      if ((call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) {
+        const Function& target = call->function();
+        TRACE_INLINING(OS::Print(
+            "  => %s (deopt count %d)\n     Bailout: cold %f\n",
+            target.ToCString(),
+            target.deoptimization_counter(),
+            call_info[call_idx].ratio));
+        continue;
+      }
       GrowableArray<Value*> arguments(call->ArgumentCount());
       for (int i = 0; i < call->ArgumentCount(); ++i) {
         arguments.Add(call->PushArgumentAt(i)->value());
@@ -1099,6 +1122,7 @@
         const ICData& new_checks = ICData::ZoneHandle(
             ICData::New(Function::Handle(old_checks.function()),
                         String::Handle(old_checks.target_name()),
+                        Array::Handle(old_checks.arguments_descriptor()),
                         old_checks.deopt_id(),
                         1));  // Number of args tested.
         new_checks.AddReceiverCheck(inlined_variants_[i].cid,
@@ -1223,6 +1247,7 @@
     const ICData& new_checks = ICData::ZoneHandle(
         ICData::New(Function::Handle(old_checks.function()),
                     String::Handle(old_checks.target_name()),
+                    Array::Handle(old_checks.arguments_descriptor()),
                     old_checks.deopt_id(),
                     1));  // Number of args tested.
     for (intptr_t i = 0; i < non_inlined_variants_.length(); ++i) {
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 36646d3..231b65d 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -33,6 +33,8 @@
 DEFINE_FLAG(bool, truncating_left_shift, true,
     "Optimize left shift to truncate if possible");
 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis.");
+DEFINE_FLAG(bool, trace_load_optimization, false,
+    "Print live sets for load optimization pass.");
 DECLARE_FLAG(bool, eliminate_type_checks);
 DECLARE_FLAG(bool, enable_type_checks);
 DECLARE_FLAG(bool, trace_type_check_elimination);
@@ -120,6 +122,7 @@
     ICData& ic_data = ICData::ZoneHandle(ICData::New(
         flow_graph_->parsed_function().function(),
         call->function_name(),
+        Object::null_array(),  // Dummy argument descriptor.
         call->deopt_id(),
         class_ids.length()));
     ic_data.AddReceiverCheck(class_ids[0], function);
@@ -141,6 +144,7 @@
   const ICData& new_ic_data = ICData::ZoneHandle(ICData::New(
       Function::Handle(ic_data.function()),
       String::Handle(ic_data.target_name()),
+      Object::null_array(),  // Dummy argument descriptor.
       ic_data.deopt_id(),
       ic_data.num_args_tested()));
 
@@ -413,6 +417,7 @@
   InsertConversion(from_rep, to_rep, use, insert_before, deopt_target);
 }
 
+
 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) {
   const Representation from_rep = def->representation();
 
@@ -1503,6 +1508,8 @@
     return true;
   } else if (target.kind() == RawFunction::kMethodExtractor) {
     return false;
+  } else if (target.kind() == RawFunction::kNoSuchMethodDispatcher) {
+    return false;
   }
 
   // Not an implicit getter.
@@ -2109,7 +2116,8 @@
     case kTypedDataUint16ArrayCid: {
       // Check that value is always smi.
       value_check = ICData::New(Function::Handle(),
-                                String::Handle(),
+                                Object::null_string(),
+                                Object::null_array(),
                                 Isolate::kNoDeoptId,
                                 1);
       value_check.AddReceiverCheck(kSmiCid, Function::Handle());
@@ -2122,7 +2130,8 @@
       // before storing to handle the mint case, too.
       if (call->ic_data()->deopt_reason() == kDeoptUnknown) {
         value_check = ICData::New(Function::Handle(),
-                                  String::Handle(),
+                                  Object::null_string(),
+                                  Object::null_array(),  // Dummy args. descr.
                                   Isolate::kNoDeoptId,
                                   1);
         value_check.AddReceiverCheck(kSmiCid, Function::Handle());
@@ -2132,7 +2141,8 @@
     case kTypedDataFloat64ArrayCid: {
       // Check that value is always double.
       value_check = ICData::New(Function::Handle(),
-                                String::Handle(),
+                                Object::null_string(),
+                                Object::null_array(),  // Dummy args. descr.
                                 Isolate::kNoDeoptId,
                                 1);
       value_check.AddReceiverCheck(kDoubleCid, Function::Handle());
@@ -2141,7 +2151,8 @@
     case kTypedDataFloat32x4ArrayCid: {
       // Check that value is always Float32x4.
       value_check = ICData::New(Function::Handle(),
-                                String::Handle(),
+                                Object::null_string(),
+                                Object::null_array(),  // Dummy args. descr.
                                 Isolate::kNoDeoptId,
                                 1);
       value_check.AddReceiverCheck(kFloat32x4Cid, Function::Handle());
@@ -2466,6 +2477,18 @@
         new Value(call->ArgumentAt(4)),
         call->deopt_id());
     ReplaceCall(call, con);
+  } else if (recognized_kind == MethodRecognizer::kObjectConstructor) {
+    // Remove the original push arguments.
+    for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
+      PushArgumentInstr* push = call->PushArgumentAt(i);
+      push->ReplaceUsesWith(push->value()->definition());
+      push->RemoveFromGraph();
+    }
+    // Manually replace call with global null constant. ReplaceCall can't
+    // be used for definitions that are already in the graph.
+    call->ReplaceUsesWith(flow_graph_->constant_null());
+    ASSERT(current_iterator()->Current() == call);
+    current_iterator()->RemoveCurrentFromGraph();;
   }
 }
 
@@ -3502,9 +3525,9 @@
                                 intptr_t loop_header_index,
                                 Instruction* instr) {
   return (sets != NULL) &&
-      instr->HasExprId() &&
+      instr->HasPlaceId() &&
       ((*sets)[loop_header_index] != NULL) &&
-      (*sets)[loop_header_index]->Contains(instr->expr_id());
+      (*sets)[loop_header_index]->Contains(instr->place_id());
 }
 
 
@@ -3533,7 +3556,7 @@
         Instruction* current = it.Current();
         if ((current->AllowsCSE() &&
              block_effects->CanBeMovedTo(current, pre_header)) ||
-             IsLoopInvariantLoad(loop_invariant_loads, i, current)) {
+            IsLoopInvariantLoad(loop_invariant_loads, i, current)) {
           bool inputs_loop_invariant = true;
           for (int i = 0; i < current->InputCount(); ++i) {
             Definition* input_def = current->InputAt(i)->definition();
@@ -3634,44 +3657,308 @@
 };
 
 
-// Set mapping alias to a list of loads sharing this alias. Additionally
-// carries a set of loads that can be aliased by side-effects, essentially
+// Place describes an abstract location (e.g. field) that IR can load
+// from or store to.
+class Place : public ValueObject {
+ public:
+  enum Kind {
+    kNone,
+
+    // Field location. For instance fields is represented as a pair of a Field
+    // object and an instance (SSA definition) that is being accessed.
+    // For static fields instance is NULL.
+    kField,
+
+    // VMField location. Represented as a pair of an instance (SSA definition)
+    // being accessed and offset to the field.
+    kVMField,
+
+    // Indexed location.
+    kIndexed,
+
+    // Current context.
+    kContext
+  };
+
+  Place(const Place& other)
+      : ValueObject(),
+        kind_(other.kind_),
+        instance_(other.instance_),
+        raw_selector_(other.raw_selector_),
+        id_(other.id_) {
+  }
+
+  // Construct a place from instruction if instruction accesses any place.
+  // Otherwise constructs kNone place.
+  Place(Instruction* instr, bool* is_load)
+      : kind_(kNone), instance_(NULL), raw_selector_(0), id_(0) {
+    switch (instr->tag()) {
+      case Instruction::kLoadField: {
+        LoadFieldInstr* load_field = instr->AsLoadField();
+        instance_ = load_field->instance()->definition();
+        if (load_field->field() != NULL) {
+          kind_ = kField;
+          field_ = load_field->field();
+        } else {
+          kind_ = kVMField;
+          offset_in_bytes_ = load_field->offset_in_bytes();
+        }
+        *is_load = true;
+        break;
+      }
+
+      case Instruction::kStoreInstanceField: {
+        StoreInstanceFieldInstr* store_instance_field =
+            instr->AsStoreInstanceField();
+        kind_ = kField;
+        instance_ = store_instance_field->instance()->definition();
+        field_ = &store_instance_field->field();
+        break;
+      }
+
+      case Instruction::kStoreVMField: {
+        StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField();
+        kind_ = kVMField;
+        instance_ = store_vm_field->dest()->definition();
+        offset_in_bytes_ = store_vm_field->offset_in_bytes();
+        break;
+      }
+
+      case Instruction::kLoadStaticField:
+        kind_ = kField;
+        field_ = &instr->AsLoadStaticField()->StaticField();
+        *is_load = true;
+        break;
+
+      case Instruction::kStoreStaticField:
+        kind_ = kField;
+        field_ = &instr->AsStoreStaticField()->field();
+        break;
+
+      case Instruction::kLoadIndexed: {
+        LoadIndexedInstr* load_indexed = instr->AsLoadIndexed();
+        kind_ = kIndexed;
+        instance_ = load_indexed->array()->definition();
+        index_ = load_indexed->index()->definition();
+        *is_load = true;
+        break;
+      }
+
+      case Instruction::kStoreIndexed: {
+        StoreIndexedInstr* store_indexed = instr->AsStoreIndexed();
+        kind_ = kIndexed;
+        instance_ = store_indexed->array()->definition();
+        index_ = store_indexed->index()->definition();
+        break;
+      }
+
+      case Instruction::kCurrentContext:
+        kind_ = kContext;
+        *is_load = true;
+        break;
+
+      case Instruction::kChainContext:
+      case Instruction::kStoreContext:
+        kind_ = kContext;
+        break;
+
+      default:
+        break;
+    }
+  }
+
+  intptr_t id() const { return id_; }
+  void set_id(intptr_t id) { id_ = id; }
+
+  Kind kind() const { return kind_; }
+
+  Definition* instance() const {
+    ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed));
+    return instance_;
+  }
+
+  void set_instance(Definition* def) {
+    ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed));
+    instance_ = def;
+  }
+
+  const Field& field() const {
+    ASSERT(kind_ == kField);
+    return *field_;
+  }
+
+  intptr_t offset_in_bytes() const {
+    ASSERT(kind_ == kVMField);
+    return offset_in_bytes_;
+  }
+
+  Definition* index() const {
+    ASSERT(kind_ == kIndexed);
+    return index_;
+  }
+
+  const char* ToCString() const {
+    switch (kind_) {
+      case kNone:
+        return "<none>";
+
+      case kField: {
+        const char* field_name = String::Handle(field().name()).ToCString();
+        if (instance() == NULL) {
+          return field_name;
+        }
+        return Isolate::Current()->current_zone()->PrintToString(
+            "<v%"Pd".%s>", instance()->ssa_temp_index(), field_name);
+      }
+
+      case kVMField: {
+        return Isolate::Current()->current_zone()->PrintToString(
+            "<v%"Pd"@%"Pd">", instance()->ssa_temp_index(), offset_in_bytes());
+      }
+
+      case kIndexed: {
+        return Isolate::Current()->current_zone()->PrintToString(
+            "<v%"Pd"[v%"Pd"]>",
+            instance()->ssa_temp_index(),
+            index()->ssa_temp_index());
+      }
+
+      case kContext:
+        return "<context>";
+    }
+    UNREACHABLE();
+    return "<?>";
+  }
+
+  bool IsFinalField() const {
+    return (kind() == kField) && field().is_final();
+  }
+
+  intptr_t Hashcode() const {
+    return (kind_ * 63 + reinterpret_cast<intptr_t>(instance_)) * 31 +
+        FieldHashcode();
+  }
+
+  bool Equals(Place* other) const {
+    return (kind_ == other->kind_) &&
+        (instance_ == other->instance_) &&
+        SameField(other);
+  }
+
+  // Create a zone allocated copy of this place.
+  static Place* Wrap(const Place& place);
+
+ private:
+  bool SameField(Place* other) const {
+    return (kind_ == kField) ? (field().raw() == other->field().raw())
+                             : (offset_in_bytes_ == other->offset_in_bytes_);
+  }
+
+  intptr_t FieldHashcode() const {
+    return (kind_ == kField) ? reinterpret_cast<intptr_t>(field().raw())
+                             : offset_in_bytes_;
+  }
+
+  Kind kind_;
+  Definition* instance_;
+  union {
+    intptr_t raw_selector_;
+    const Field* field_;
+    intptr_t offset_in_bytes_;
+    Definition* index_;
+  };
+
+  intptr_t id_;
+};
+
+
+class ZonePlace : public ZoneAllocated {
+ public:
+  explicit ZonePlace(const Place& place) : place_(place) { }
+
+  Place* place() { return &place_; }
+
+ private:
+  Place place_;
+};
+
+
+Place* Place::Wrap(const Place& place) {
+  return (new ZonePlace(place))->place();
+}
+
+
+// Correspondence between places connected through outgoing phi moves on the
+// edge that targets join.
+class PhiPlaceMoves : public ZoneAllocated {
+ public:
+  // Record a move from the place with id |from| to the place with id |to| at
+  // the given block.
+  void CreateOutgoingMove(BlockEntryInstr* block, intptr_t from, intptr_t to) {
+    const intptr_t block_num = block->preorder_number();
+    while (moves_.length() <= block_num) {
+      moves_.Add(NULL);
+    }
+
+    if (moves_[block_num] == NULL) {
+      moves_[block_num] = new ZoneGrowableArray<Move>(5);
+    }
+
+    moves_[block_num]->Add(Move(from, to));
+  }
+
+  class Move {
+   public:
+    Move(intptr_t from, intptr_t to) : from_(from), to_(to) { }
+
+    intptr_t from() const { return from_; }
+    intptr_t to() const { return to_; }
+
+   private:
+    intptr_t from_;
+    intptr_t to_;
+  };
+
+  typedef const ZoneGrowableArray<Move>* MovesList;
+
+  MovesList GetOutgoingMoves(BlockEntryInstr* block) const {
+    const intptr_t block_num = block->preorder_number();
+    return (block_num < moves_.length()) ?
+        moves_[block_num] : NULL;
+  }
+
+ private:
+  GrowableArray<ZoneGrowableArray<Move>* > moves_;
+};
+
+
+// A map from aliases to a set of places sharing the alias. Additionally
+// carries a set of places that can be aliased by side-effects, essentially
 // those that are affected by calls.
 class AliasedSet : public ZoneAllocated {
  public:
-  explicit AliasedSet(intptr_t max_expr_id)
-      : max_expr_id_(max_expr_id),
+  explicit AliasedSet(ZoneGrowableArray<Place*>* places,
+                      PhiPlaceMoves* phi_moves)
+      : places_(*places),
+        phi_moves_(phi_moves),
         sets_(),
-        // BitVector constructor throws if requested length is 0.
-        aliased_by_effects_(max_expr_id > 0 ? new BitVector(max_expr_id)
-                                            : NULL),
+        aliased_by_effects_(new BitVector(places->length())),
         max_field_id_(0),
         field_ids_() { }
 
-  Alias ComputeAliasForLoad(Definition* defn) {
-    if (defn->IsLoadIndexed()) {
-      // We are assuming that LoadField is never used to load the first word.
-      return Alias::Indexes();
-    }
-
-    LoadFieldInstr* load_field = defn->AsLoadField();
-    if (load_field != NULL) {
-      if (load_field->field() != NULL) {
-        Definition* instance = load_field->instance()->definition();
-        return Alias::Field(GetInstanceFieldId(instance, *load_field->field()));
-      } else {
-        return Alias::VMField(load_field->offset_in_bytes());
-      }
-    }
-
-    if (defn->IsCurrentContext()) {
-      return Alias::CurrentContext();
-    }
-
-    LoadStaticFieldInstr* load_static_field = defn->AsLoadStaticField();
-    if (load_static_field != NULL) {
-      return Alias::Field(GetFieldId(kAnyInstance,
-                                     load_static_field->StaticField()));
+  Alias ComputeAlias(Place* place) {
+    switch (place->kind()) {
+      case Place::kIndexed:
+        return Alias::Indexes();
+      case Place::kField:
+        return Alias::Field(
+            GetInstanceFieldId(place->instance(), place->field()));
+      case Place::kVMField:
+        return Alias::VMField(place->offset_in_bytes());
+      case Place::kContext:
+        return Alias::CurrentContext();
+      case Place::kNone:
+        UNREACHABLE();
     }
 
     UNREACHABLE();
@@ -3708,24 +3995,21 @@
     return Alias::None();
   }
 
-  bool Contains(const Alias alias) {
-    const intptr_t idx = alias.ToIndex();
-    return (idx < sets_.length()) && (sets_[idx] != NULL);
-  }
-
   BitVector* Get(const Alias alias) {
-    ASSERT(Contains(alias));
-    return sets_[alias.ToIndex()];
+    const intptr_t idx = alias.ToIndex();
+    return (idx < sets_.length()) ? sets_[idx] : NULL;
   }
 
-  void AddRepresentative(Definition* defn) {
-    AddIdForAlias(ComputeAliasForLoad(defn), defn->expr_id());
-    if (!IsIndependentFromEffects(defn)) {
-      aliased_by_effects_->Add(defn->expr_id());
+  void AddRepresentative(Place* place) {
+    if (!place->IsFinalField()) {
+      AddIdForAlias(ComputeAlias(place), place->id());
+      if (!IsIndependentFromEffects(place)) {
+        aliased_by_effects_->Add(place->id());
+      }
     }
   }
 
-  void AddIdForAlias(const Alias alias, intptr_t expr_id) {
+  void AddIdForAlias(const Alias alias, intptr_t place_id) {
     const intptr_t idx = alias.ToIndex();
 
     while (sets_.length() <= idx) {
@@ -3733,17 +4017,36 @@
     }
 
     if (sets_[idx] == NULL) {
-      sets_[idx] = new BitVector(max_expr_id_);
+      sets_[idx] = new BitVector(max_place_id());
     }
 
-    sets_[idx]->Add(expr_id);
+    sets_[idx]->Add(place_id);
   }
 
-  intptr_t max_expr_id() const { return max_expr_id_; }
-  bool IsEmpty() const { return max_expr_id_ == 0; }
+  intptr_t max_place_id() const { return places().length(); }
+  bool IsEmpty() const { return max_place_id() == 0; }
 
   BitVector* aliased_by_effects() const { return aliased_by_effects_; }
 
+  const ZoneGrowableArray<Place*>& places() const {
+    return places_;
+  }
+
+  void PrintSet(BitVector* set) {
+    bool comma = false;
+    for (BitVector::Iterator it(set);
+         !it.Done();
+         it.Advance()) {
+      if (comma) {
+        OS::Print(", ");
+      }
+      OS::Print("%s", places_[it.Current()]->ToCString());
+      comma = true;
+    }
+  }
+
+  const PhiPlaceMoves* phi_moves() const { return phi_moves_; }
+
  private:
   // Get id assigned to the given field. Assign a new id if the field is seen
   // for the first time.
@@ -3770,14 +4073,16 @@
   // If multiple SSA names can point to the same object then we use
   // kAnyInstance instead of a concrete SSA name.
   intptr_t GetInstanceFieldId(Definition* defn, const Field& field) {
-    ASSERT(!field.is_static());
+    ASSERT(field.is_static() == (defn == NULL));
 
     intptr_t instance_id = kAnyInstance;
 
-    AllocateObjectInstr* alloc = defn->AsAllocateObject();
-    if ((alloc != NULL) && !CanBeAliased(alloc)) {
-      instance_id = alloc->ssa_temp_index();
-      ASSERT(instance_id != kAnyInstance);
+    if (defn != NULL) {
+      AllocateObjectInstr* alloc = defn->AsAllocateObject();
+      if ((alloc != NULL) && !CanBeAliased(alloc)) {
+        instance_id = alloc->ssa_temp_index();
+        ASSERT(instance_id != kAnyInstance);
+      }
     }
 
     return GetFieldId(instance_id, field);
@@ -3820,9 +4125,8 @@
   // Returns true if the given load is unaffected by external side-effects.
   // This essentially means that no stores to the same location can
   // occur in other functions.
-  bool IsIndependentFromEffects(Definition* defn) {
-    LoadFieldInstr* load_field = defn->AsLoadField();
-    if (load_field != NULL) {
+  bool IsIndependentFromEffects(Place* place) {
+    if (place->IsFinalField()) {
       // Note that we can't use LoadField's is_immutable attribute here because
       // some VM-fields (those that have no corresponding Field object and
       // accessed through offset alone) can share offset but have different
@@ -3835,19 +4139,14 @@
       // conservative assumption for the VM-properties.
       // TODO(vegorov): disambiguate immutable and non-immutable VM-fields with
       // the same offset e.g. through recognized kind.
-      if ((load_field->field() != NULL) &&
-          (load_field->field()->is_final())) {
-        return true;
-      }
-
-      AllocateObjectInstr* alloc =
-          load_field->instance()->definition()->AsAllocateObject();
-      return (alloc != NULL) && !CanBeAliased(alloc);
+      return true;
     }
 
-    LoadStaticFieldInstr* load_static_field = defn->AsLoadStaticField();
-    if (load_static_field != NULL) {
-      return load_static_field->StaticField().is_final();
+    if (((place->kind() == Place::kField) ||
+         (place->kind() == Place::kVMField)) &&
+        (place->instance() != NULL)) {
+      AllocateObjectInstr* alloc = place->instance()->AsAllocateObject();
+      return (alloc != NULL) && !CanBeAliased(alloc);
     }
 
     return false;
@@ -3890,7 +4189,9 @@
     Value value_;
   };
 
-  const intptr_t max_expr_id_;
+  const ZoneGrowableArray<Place*>& places_;
+
+  const PhiPlaceMoves* phi_moves_;
 
   // Maps alias index to a set of ssa indexes corresponding to loads with the
   // given alias.
@@ -3933,114 +4234,69 @@
 }
 
 
-// KeyValueTrait used for numbering of loads. Allows to lookup loads
-// corresponding to stores.
-class LoadKeyValueTrait {
- public:
-  typedef Definition* Value;
-  typedef Instruction* Key;
-  typedef Definition* Pair;
+static bool IsPhiDependentPlace(Place* place) {
+  return ((place->kind() == Place::kField) ||
+          (place->kind() == Place::kVMField)) &&
+        (place->instance() != NULL) &&
+        place->instance()->IsPhi();
+}
 
-  static Key KeyOf(Pair kv) {
-    return kv;
-  }
 
-  static Value ValueOf(Pair kv) {
-    return kv;
-  }
+// For each place that depends on a phi ensure that equivalent places
+// corresponding to phi input are numbered and record outgoing phi moves
+// for each block which establish correspondence between phi dependent place
+// and phi input's place that is flowing in.
+static PhiPlaceMoves* ComputePhiMoves(
+    DirectChainedHashMap<PointerKeyValueTrait<Place> >* map,
+    ZoneGrowableArray<Place*>* places) {
+  PhiPlaceMoves* phi_moves = new PhiPlaceMoves();
 
-  static inline intptr_t Hashcode(Key key) {
-    intptr_t object = 0;
-    intptr_t location = 0;
+  for (intptr_t i = 0; i < places->length(); i++) {
+    Place* place = (*places)[i];
 
-    if (key->IsLoadIndexed()) {
-      LoadIndexedInstr* load_indexed = key->AsLoadIndexed();
-      object = load_indexed->array()->definition()->ssa_temp_index();
-      location = load_indexed->index()->definition()->ssa_temp_index();
-    } else if (key->IsStoreIndexed()) {
-      StoreIndexedInstr* store_indexed = key->AsStoreIndexed();
-      object = store_indexed->array()->definition()->ssa_temp_index();
-      location = store_indexed->index()->definition()->ssa_temp_index();
-    } else if (key->IsLoadField()) {
-      LoadFieldInstr* load_field = key->AsLoadField();
-      object = load_field->instance()->definition()->ssa_temp_index();
-      location = load_field->offset_in_bytes();
-    } else if (key->IsStoreInstanceField()) {
-      StoreInstanceFieldInstr* store_field = key->AsStoreInstanceField();
-      object = store_field->instance()->definition()->ssa_temp_index();
-      location = store_field->field().Offset();
-    } else if (key->IsStoreVMField()) {
-      StoreVMFieldInstr* store_field = key->AsStoreVMField();
-      object = store_field->dest()->definition()->ssa_temp_index();
-      location = store_field->offset_in_bytes();
-    } else if (key->IsLoadStaticField()) {
-      LoadStaticFieldInstr* load_static_field = key->AsLoadStaticField();
-      object = String::Handle(load_static_field->StaticField().name()).Hash();
-    } else if (key->IsStoreStaticField()) {
-      StoreStaticFieldInstr* store_static_field = key->AsStoreStaticField();
-      object = String::Handle(store_static_field->field().name()).Hash();
-    } else {
-      ASSERT(key->IsStoreContext() ||
-             key->IsCurrentContext() ||
-             key->IsChainContext());
-    }
+    if (IsPhiDependentPlace(place)) {
+      PhiInstr* phi = place->instance()->AsPhi();
+      BlockEntryInstr* block = phi->GetBlock();
 
-    return object * 31 + location;
-  }
-
-  static inline bool IsKeyEqual(Pair kv, Key key) {
-    if (kv->Equals(key)) return true;
-
-    if (kv->IsLoadIndexed()) {
-      if (key->IsStoreIndexed()) {
-        LoadIndexedInstr* load_indexed = kv->AsLoadIndexed();
-        StoreIndexedInstr* store_indexed = key->AsStoreIndexed();
-        return load_indexed->array()->Equals(store_indexed->array()) &&
-               load_indexed->index()->Equals(store_indexed->index());
+      if (FLAG_trace_optimization) {
+        OS::Print("phi dependent place %s\n", place->ToCString());
       }
-      return false;
-    }
 
-    if (kv->IsLoadStaticField()) {
-      if (key->IsStoreStaticField()) {
-        LoadStaticFieldInstr* load_static_field = kv->AsLoadStaticField();
-        StoreStaticFieldInstr* store_static_field = key->AsStoreStaticField();
-        return load_static_field->StaticField().raw() ==
-            store_static_field->field().raw();
+      Place input_place(*place);
+      for (intptr_t j = 0; j < phi->InputCount(); j++) {
+        input_place.set_instance(phi->InputAt(j)->definition());
+
+        Place* result = map->Lookup(&input_place);
+        if (result == NULL) {
+          input_place.set_id(places->length());
+          result = Place::Wrap(input_place);
+          map->Insert(result);
+          places->Add(result);
+          if (FLAG_trace_optimization) {
+            OS::Print("  adding place %s as %"Pd"\n",
+                      result->ToCString(),
+                      result->id());
+          }
+        }
+
+        phi_moves->CreateOutgoingMove(block->PredecessorAt(j),
+                                      result->id(),
+                                      place->id());
       }
-      return false;
     }
-
-    if (kv->IsCurrentContext()) {
-      return key->IsStoreContext() || key->IsChainContext();
-    }
-
-    ASSERT(kv->IsLoadField());
-    LoadFieldInstr* load_field = kv->AsLoadField();
-    if (key->IsStoreVMField()) {
-      StoreVMFieldInstr* store_field = key->AsStoreVMField();
-      return load_field->instance()->Equals(store_field->dest()) &&
-             (load_field->offset_in_bytes() == store_field->offset_in_bytes());
-    } else if (key->IsStoreInstanceField()) {
-      StoreInstanceFieldInstr* store_field = key->AsStoreInstanceField();
-      return load_field->instance()->Equals(store_field->instance()) &&
-             (load_field->offset_in_bytes() == store_field->field().Offset());
-    }
-
-    return false;
   }
-};
 
+  return phi_moves;
+}
 
-static AliasedSet* NumberLoadExpressions(
+static AliasedSet* NumberPlaces(
     FlowGraph* graph,
-    DirectChainedHashMap<LoadKeyValueTrait>* map) {
-  intptr_t expr_id = 0;
-
+    DirectChainedHashMap<PointerKeyValueTrait<Place> >* map) {
   // Loads representing different expression ids will be collected and
   // used to build per offset kill sets.
-  GrowableArray<Definition*> loads(10);
+  ZoneGrowableArray<Place*>* places = new ZoneGrowableArray<Place*>(10);
 
+  bool has_loads = false;
   for (BlockIterator it = graph->reverse_postorder_iterator();
        !it.Done();
        it.Advance()) {
@@ -4048,33 +4304,44 @@
     for (ForwardInstructionIterator instr_it(block);
          !instr_it.Done();
          instr_it.Advance()) {
-      Definition* defn = instr_it.Current()->AsDefinition();
-      if ((defn == NULL) || !IsLoadEliminationCandidate(defn)) {
+      Instruction* instr = instr_it.Current();
+
+      Place place(instr, &has_loads);
+      if (place.kind() == Place::kNone) {
         continue;
       }
-      Definition* result = map->Lookup(defn);
+
+      Place* result = map->Lookup(&place);
       if (result == NULL) {
-        map->Insert(defn);
-        defn->set_expr_id(expr_id++);
-        loads.Add(defn);
-      } else {
-        defn->set_expr_id(result->expr_id());
+        place.set_id(places->length());
+        result = Place::Wrap(place);
+        map->Insert(result);
+        places->Add(result);
+
+        if (FLAG_trace_optimization) {
+          OS::Print("numbering %s as %"Pd"\n",
+                    result->ToCString(),
+                    result->id());
+        }
       }
 
-      if (FLAG_trace_optimization) {
-        OS::Print("load v%"Pd" is numbered as %"Pd"\n",
-                  defn->ssa_temp_index(),
-                  defn->expr_id());
-      }
+      instr->set_place_id(result->id());
     }
   }
 
-  // Build aliasing sets mapping aliases to loads.
-  AliasedSet* aliased_set = new AliasedSet(expr_id);
-  for (intptr_t i = 0; i < loads.length(); i++) {
-    Definition* defn = loads[i];
-    aliased_set->AddRepresentative(defn);
+  if (!has_loads) {
+    return NULL;
   }
+
+  PhiPlaceMoves* phi_moves = ComputePhiMoves(map, places);
+
+  // Build aliasing sets mapping aliases to loads.
+  AliasedSet* aliased_set = new AliasedSet(places, phi_moves);
+  for (intptr_t i = 0; i < places->length(); i++) {
+    Place* place = (*places)[i];
+    aliased_set->AddRepresentative(place);
+  }
+
   return aliased_set;
 }
 
@@ -4083,7 +4350,7 @@
  public:
   LoadOptimizer(FlowGraph* graph,
                 AliasedSet* aliased_set,
-                DirectChainedHashMap<LoadKeyValueTrait>* map)
+                DirectChainedHashMap<PointerKeyValueTrait<Place> >* map)
       : graph_(graph),
         map_(map),
         aliased_set_(aliased_set),
@@ -4099,10 +4366,10 @@
         forwarded_(false) {
     const intptr_t num_blocks = graph_->preorder().length();
     for (intptr_t i = 0; i < num_blocks; i++) {
-      out_.Add(new BitVector(aliased_set_->max_expr_id()));
-      gen_.Add(new BitVector(aliased_set_->max_expr_id()));
-      kill_.Add(new BitVector(aliased_set_->max_expr_id()));
-      in_.Add(new BitVector(aliased_set_->max_expr_id()));
+      out_.Add(NULL);
+      gen_.Add(new BitVector(aliased_set_->max_place_id()));
+      kill_.Add(new BitVector(aliased_set_->max_place_id()));
+      in_.Add(new BitVector(aliased_set_->max_place_id()));
 
       exposed_values_.Add(NULL);
       out_values_.Add(NULL);
@@ -4111,10 +4378,13 @@
 
   static bool OptimizeGraph(FlowGraph* graph) {
     ASSERT(FLAG_load_cse);
+    if (FLAG_trace_load_optimization) {
+      FlowGraphPrinter::PrintGraph("Before LoadOptimizer", graph);
+    }
 
-    DirectChainedHashMap<LoadKeyValueTrait> map;
-    AliasedSet* aliased_set = NumberLoadExpressions(graph, &map);
-    if (!aliased_set->IsEmpty()) {
+    DirectChainedHashMap<PointerKeyValueTrait<Place> > map;
+    AliasedSet* aliased_set = NumberPlaces(graph, &map);
+    if ((aliased_set != NULL) && !aliased_set->IsEmpty()) {
       // If any loads were forwarded return true from Optimize to run load
       // forwarding again. This will allow to forward chains of loads.
       // This is especially important for context variables as they are built
@@ -4130,12 +4400,18 @@
  private:
   bool Optimize() {
     ComputeInitialSets();
+    ComputeOutSets();
     ComputeOutValues();
     if (graph_->is_licm_allowed()) {
       MarkLoopInvariantLoads();
     }
     ForwardLoads();
     EmitPhis();
+
+    if (FLAG_trace_load_optimization) {
+      FlowGraphPrinter::PrintGraph("After LoadOptimizer", graph_);
+    }
+
     return forwarded_;
   }
 
@@ -4146,6 +4422,8 @@
   // Loads that are locally redundant will be replaced as we go through
   // instructions.
   void ComputeInitialSets() {
+    BitVector* forwarded_loads = new BitVector(aliased_set_->max_place_id());
+
     for (BlockIterator block_it = graph_->reverse_postorder_iterator();
          !block_it.Done();
          block_it.Advance()) {
@@ -4166,31 +4444,36 @@
         const Alias alias = aliased_set_->ComputeAliasForStore(instr);
         if (!alias.IsNone()) {
           // Interfering stores kill only loads from the same offset.
-          if (aliased_set_->Contains(alias)) {
-            BitVector* killed = aliased_set_->Get(alias);
+          BitVector* killed = aliased_set_->Get(alias);
+
+          if (killed != NULL) {
             kill->AddAll(killed);
             // There is no need to clear out_values when clearing GEN set
             // because only those values that are in the GEN set
             // will ever be used.
             gen->RemoveAll(killed);
+          }
 
-            // Only forward stores to normal arrays and float64 arrays
-            // to loads because other array stores (intXX/uintXX/float32)
-            // may implicitly convert the value stored.
-            StoreIndexedInstr* array_store = instr->AsStoreIndexed();
-            if (array_store == NULL ||
-                array_store->class_id() == kArrayCid ||
-                array_store->class_id() == kTypedDataFloat64ArrayCid) {
-              Definition* load = map_->Lookup(instr);
-              if (load != NULL) {
-                // Store has a corresponding numbered load. Try forwarding
-                // stored value to it.
-                gen->Add(load->expr_id());
-                if (out_values == NULL) out_values = CreateBlockOutValues();
-                (*out_values)[load->expr_id()] = GetStoredValue(instr);
-              }
+          // Only forward stores to normal arrays and float64 arrays
+          // to loads because other array stores (intXX/uintXX/float32)
+          // may implicitly convert the value stored.
+          StoreIndexedInstr* array_store = instr->AsStoreIndexed();
+          if (array_store == NULL ||
+              array_store->class_id() == kArrayCid ||
+              array_store->class_id() == kTypedDataFloat64ArrayCid) {
+            bool is_load = false;
+            Place store_place(instr, &is_load);
+            ASSERT(!is_load);
+            Place* place = map_->Lookup(&store_place);
+            if (place != NULL) {
+              // Store has a corresponding numbered place that might have a
+              // load. Try forwarding stored value to it.
+              gen->Add(place->id());
+              if (out_values == NULL) out_values = CreateBlockOutValues();
+              (*out_values)[place->id()] = GetStoredValue(instr);
             }
           }
+
           ASSERT(!instr->IsDefinition() ||
                  !IsLoadEliminationCandidate(instr->AsDefinition()));
           continue;
@@ -4240,9 +4523,9 @@
             LoadFieldInstr* load = use->instruction()->AsLoadField();
             if (load != NULL) {
               // Found a load. Initialize current value of the field to null.
-              gen->Add(load->expr_id());
+              gen->Add(load->place_id());
               if (out_values == NULL) out_values = CreateBlockOutValues();
-              (*out_values)[load->expr_id()] = graph_->constant_null();
+              (*out_values)[load->place_id()] = graph_->constant_null();
             }
           }
           continue;
@@ -4252,12 +4535,12 @@
           continue;
         }
 
-        const intptr_t expr_id = defn->expr_id();
-        if (gen->Contains(expr_id)) {
+        const intptr_t place_id = defn->place_id();
+        if (gen->Contains(place_id)) {
           // This is a locally redundant load.
-          ASSERT((out_values != NULL) && ((*out_values)[expr_id] != NULL));
+          ASSERT((out_values != NULL) && ((*out_values)[place_id] != NULL));
 
-          Definition* replacement = (*out_values)[expr_id];
+          Definition* replacement = (*out_values)[place_id];
           EnsureSSATempIndex(graph_, defn, replacement);
           if (FLAG_trace_optimization) {
             OS::Print("Replacing load v%"Pd" with v%"Pd"\n",
@@ -4269,7 +4552,7 @@
           instr_it.RemoveCurrentFromGraph();
           forwarded_ = true;
           continue;
-        } else if (!kill->Contains(expr_id)) {
+        } else if (!kill->Contains(place_id)) {
           // This is an exposed load: it is the first representative of a
           // given expression id and it is not killed on the path from
           // the block entry.
@@ -4277,33 +4560,60 @@
             static const intptr_t kMaxExposedValuesInitialSize = 5;
             exposed_values = new ZoneGrowableArray<Definition*>(
                 Utils::Minimum(kMaxExposedValuesInitialSize,
-                               aliased_set_->max_expr_id()));
+                               aliased_set_->max_place_id()));
           }
 
           exposed_values->Add(defn);
         }
 
-        gen->Add(expr_id);
+        gen->Add(place_id);
 
         if (out_values == NULL) out_values = CreateBlockOutValues();
-        (*out_values)[expr_id] = defn;
+        (*out_values)[place_id] = defn;
       }
 
-      out_[preorder_number]->CopyFrom(gen);
+      PhiPlaceMoves::MovesList phi_moves =
+          aliased_set_->phi_moves()->GetOutgoingMoves(block);
+      if (phi_moves != NULL) {
+        PerformPhiMoves(phi_moves, gen, forwarded_loads);
+      }
+
       exposed_values_[preorder_number] = exposed_values;
       out_values_[preorder_number] = out_values;
     }
   }
 
-  // Compute OUT sets and corresponding out_values mappings by propagating them
-  // iteratively until fix point is reached.
-  // No replacement is done at this point and thus any out_value[expr_id] is
-  // changed at most once: from NULL to an actual value.
-  // When merging incoming loads we might need to create a phi.
-  // These phis are not inserted at the graph immediately because some of them
-  // might become redundant after load forwarding is done.
-  void ComputeOutValues() {
-    BitVector* temp = new BitVector(aliased_set_->max_expr_id());
+  static void PerformPhiMoves(PhiPlaceMoves::MovesList phi_moves,
+                              BitVector* out,
+                              BitVector* forwarded_loads) {
+    forwarded_loads->Clear();
+
+    for (intptr_t i = 0; i < phi_moves->length(); i++) {
+      const intptr_t from = (*phi_moves)[i].from();
+      const intptr_t to = (*phi_moves)[i].to();
+      if (from == to) continue;
+
+      if (out->Contains(from)) {
+        forwarded_loads->Add(to);
+      }
+    }
+
+    for (intptr_t i = 0; i < phi_moves->length(); i++) {
+      const intptr_t from = (*phi_moves)[i].from();
+      const intptr_t to = (*phi_moves)[i].to();
+      if (from == to) continue;
+
+      out->Remove(to);
+    }
+
+    out->AddAll(forwarded_loads);
+  }
+
+  // Compute OUT sets by propagating them iteratively until fix point
+  // is reached.
+  void ComputeOutSets() {
+    BitVector* temp = new BitVector(aliased_set_->max_place_id());
+    BitVector* forwarded_loads = new BitVector(aliased_set_->max_place_id());
 
     bool changed = true;
     while (changed) {
@@ -4321,74 +4631,160 @@
         BitVector* block_kill = kill_[preorder_number];
         BitVector* block_gen = gen_[preorder_number];
 
-        if (FLAG_trace_optimization) {
-          OS::Print("B%"Pd"", block->block_id());
-          block_in->Print();
-          block_out->Print();
-          block_kill->Print();
-          block_gen->Print();
-          OS::Print("\n");
-        }
-
-        ZoneGrowableArray<Definition*>* block_out_values =
-            out_values_[preorder_number];
-
         // Compute block_in as the intersection of all out(p) where p
         // is a predecessor of the current block.
         if (block->IsGraphEntry()) {
           temp->Clear();
         } else {
-          // TODO(vegorov): this can be optimized for the case of a single
-          // predecessor.
-          // TODO(vegorov): this can be reordered to reduce amount of operations
-          // temp->CopyFrom(first_predecessor)
           temp->SetAll();
           ASSERT(block->PredecessorCount() > 0);
           for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
             BlockEntryInstr* pred = block->PredecessorAt(i);
             BitVector* pred_out = out_[pred->preorder_number()];
-            temp->Intersect(pred_out);
+            if (pred_out != NULL) {
+              temp->Intersect(pred_out);
+            }
           }
         }
 
-        if (!temp->Equals(*block_in)) {
+        if (!temp->Equals(*block_in) || (block_out == NULL)) {
           // If IN set has changed propagate the change to OUT set.
           block_in->CopyFrom(temp);
-          if (block_out->KillAndAdd(block_kill, block_in)) {
-            // If OUT set has changed then we have new values available out of
-            // the block. Compute these values creating phi where necessary.
-            for (BitVector::Iterator it(block_out);
-                 !it.Done();
-                 it.Advance()) {
-              const intptr_t expr_id = it.Current();
 
-              if (block_out_values == NULL) {
-                out_values_[preorder_number] = block_out_values =
-                    CreateBlockOutValues();
-              }
+          temp->RemoveAll(block_kill);
+          temp->AddAll(block_gen);
 
-              if ((*block_out_values)[expr_id] == NULL) {
-                ASSERT(block->PredecessorCount() > 0);
-                (*block_out_values)[expr_id] =
-                    MergeIncomingValues(block, expr_id);
-              }
+          PhiPlaceMoves::MovesList phi_moves =
+              aliased_set_->phi_moves()->GetOutgoingMoves(block);
+          if (phi_moves != NULL) {
+            PerformPhiMoves(phi_moves, temp, forwarded_loads);
+          }
+
+          if ((block_out == NULL) || !block_out->Equals(*temp)) {
+            if (block_out == NULL) {
+              block_out = out_[preorder_number] =
+                  new BitVector(aliased_set_->max_place_id());
             }
+            block_out->CopyFrom(temp);
             changed = true;
           }
         }
-
-        if (FLAG_trace_optimization) {
-          OS::Print("after B%"Pd"", block->block_id());
-          block_in->Print();
-          block_out->Print();
-          block_kill->Print();
-          block_gen->Print();
-          OS::Print("\n");
-        }
       }
     }
   }
 
+  // Compute out_values mappings by propagating them in reverse postorder once
+  // through the graph. Generate phis on back edges where eager merge is
+  // impossible.
+  // No replacement is done at this point and thus any out_value[place_id] is
+  // changed at most once: from NULL to an actual value.
+  // When merging incoming loads we might need to create a phi.
+  // These phis are not inserted at the graph immediately because some of them
+  // might become redundant after load forwarding is done.
+  void ComputeOutValues() {
+    GrowableArray<PhiInstr*> pending_phis(5);
+    ZoneGrowableArray<Definition*>* temp_forwarded_values = NULL;
+
+    for (BlockIterator block_it = graph_->reverse_postorder_iterator();
+         !block_it.Done();
+         block_it.Advance()) {
+      BlockEntryInstr* block = block_it.Current();
+
+      const bool can_merge_eagerly = CanMergeEagerly(block);
+
+      const intptr_t preorder_number = block->preorder_number();
+
+      ZoneGrowableArray<Definition*>* block_out_values =
+          out_values_[preorder_number];
+
+
+      // If OUT set has changed then we have new values available out of
+      // the block. Compute these values creating phi where necessary.
+      for (BitVector::Iterator it(out_[preorder_number]);
+           !it.Done();
+           it.Advance()) {
+        const intptr_t place_id = it.Current();
+
+        if (block_out_values == NULL) {
+          out_values_[preorder_number] = block_out_values =
+              CreateBlockOutValues();
+        }
+
+        if ((*block_out_values)[place_id] == NULL) {
+          ASSERT(block->PredecessorCount() > 0);
+          Definition* in_value = can_merge_eagerly ?
+              MergeIncomingValues(block, place_id) : NULL;
+          if ((in_value == NULL) &&
+              (in_[preorder_number]->Contains(place_id))) {
+            PhiInstr* phi = new PhiInstr(block->AsJoinEntry(),
+                                         block->PredecessorCount());
+            phi->set_place_id(place_id);
+            pending_phis.Add(phi);
+            in_value = phi;
+          }
+          (*block_out_values)[place_id] = in_value;
+        }
+      }
+
+      // If the block has outgoing phi moves perform them. Use temporary list
+      // of values to ensure that cyclic moves are performed correctly.
+      PhiPlaceMoves::MovesList phi_moves =
+          aliased_set_->phi_moves()->GetOutgoingMoves(block);
+      if ((phi_moves != NULL) && (block_out_values != NULL)) {
+        if (temp_forwarded_values == NULL) {
+          temp_forwarded_values = CreateBlockOutValues();
+        }
+
+        for (intptr_t i = 0; i < phi_moves->length(); i++) {
+          const intptr_t from = (*phi_moves)[i].from();
+          const intptr_t to = (*phi_moves)[i].to();
+          if (from == to) continue;
+
+          (*temp_forwarded_values)[to] = (*block_out_values)[from];
+        }
+
+        for (intptr_t i = 0; i < phi_moves->length(); i++) {
+          const intptr_t from = (*phi_moves)[i].from();
+          const intptr_t to = (*phi_moves)[i].to();
+          if (from == to) continue;
+
+          (*block_out_values)[to] = (*temp_forwarded_values)[to];
+        }
+      }
+
+      if (FLAG_trace_load_optimization) {
+        OS::Print("B%"Pd"\n", block->block_id());
+        OS::Print("  IN: ");
+        aliased_set_->PrintSet(in_[preorder_number]);
+        OS::Print("\n");
+
+        OS::Print("  KILL: ");
+        aliased_set_->PrintSet(kill_[preorder_number]);
+        OS::Print("\n");
+
+        OS::Print("  OUT: ");
+        aliased_set_->PrintSet(out_[preorder_number]);
+        OS::Print("\n");
+      }
+    }
+
+    // All blocks were visited. Fill pending phis with inputs
+    // that flow on back edges.
+    for (intptr_t i = 0; i < pending_phis.length(); i++) {
+      FillPhiInputs(pending_phis[i]);
+    }
+  }
+
+  bool CanMergeEagerly(BlockEntryInstr* block) {
+    for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
+      BlockEntryInstr* pred = block->PredecessorAt(i);
+      if (pred->postorder_number() < block->postorder_number()) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   void MarkLoopInvariantLoads() {
     const ZoneGrowableArray<BlockEntryInstr*>& loop_headers =
         graph_->loop_headers();
@@ -4404,7 +4800,7 @@
         continue;
       }
 
-      BitVector* loop_gen = new BitVector(aliased_set_->max_expr_id());
+      BitVector* loop_gen = new BitVector(aliased_set_->max_place_id());
       for (BitVector::Iterator loop_it(header->loop_info());
            !loop_it.Done();
            loop_it.Advance()) {
@@ -4421,8 +4817,8 @@
 
       if (FLAG_trace_optimization) {
         for (BitVector::Iterator it(loop_gen); !it.Done(); it.Advance()) {
-          OS::Print("load %"Pd" is loop invariant for B%"Pd"\n",
-                    it.Current(),
+          OS::Print("place %s is loop invariant for B%"Pd"\n",
+                    aliased_set_->places()[it.Current()]->ToCString(),
                     header->block_id());
         }
       }
@@ -4436,41 +4832,53 @@
   // Compute incoming value for the given expression id.
   // Will create a phi if different values are incoming from multiple
   // predecessors.
-  Definition* MergeIncomingValues(BlockEntryInstr* block, intptr_t expr_id) {
+  Definition* MergeIncomingValues(BlockEntryInstr* block, intptr_t place_id) {
     // First check if the same value is coming in from all predecessors.
+    static Definition* const kDifferentValuesMarker =
+        reinterpret_cast<Definition*>(-1);
     Definition* incoming = NULL;
     for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
       BlockEntryInstr* pred = block->PredecessorAt(i);
       ZoneGrowableArray<Definition*>* pred_out_values =
           out_values_[pred->preorder_number()];
-      if (incoming == NULL) {
-        incoming = (*pred_out_values)[expr_id];
-      } else if (incoming != (*pred_out_values)[expr_id]) {
-        incoming = NULL;
-        break;
+      if ((pred_out_values == NULL) || ((*pred_out_values)[place_id] == NULL)) {
+        return NULL;
+      } else if (incoming == NULL) {
+        incoming = (*pred_out_values)[place_id];
+      } else if (incoming != (*pred_out_values)[place_id]) {
+        incoming = kDifferentValuesMarker;
       }
     }
 
-    if (incoming != NULL) {
+    if (incoming != kDifferentValuesMarker) {
+      ASSERT(incoming != NULL);
       return incoming;
     }
 
     // Incoming values are different. Phi is required to merge.
     PhiInstr* phi = new PhiInstr(
         block->AsJoinEntry(), block->PredecessorCount());
+    phi->set_place_id(place_id);
+    FillPhiInputs(phi);
+    return phi;
+  }
+
+  void FillPhiInputs(PhiInstr* phi) {
+    BlockEntryInstr* block = phi->GetBlock();
+    const intptr_t place_id = phi->place_id();
 
     for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
       BlockEntryInstr* pred = block->PredecessorAt(i);
       ZoneGrowableArray<Definition*>* pred_out_values =
           out_values_[pred->preorder_number()];
-      ASSERT((*pred_out_values)[expr_id] != NULL);
+      ASSERT((*pred_out_values)[place_id] != NULL);
 
       // Sets of outgoing values are not linked into use lists so
       // they might contain values that were replaced and removed
       // from the graph by this iteration.
       // To prevent using them we additionally mark definitions themselves
       // as replaced and store a pointer to the replacement.
-      Definition* replacement = (*pred_out_values)[expr_id]->Replacement();
+      Definition* replacement = (*pred_out_values)[place_id]->Replacement();
       Value* input = new Value(replacement);
       phi->SetInputAt(i, input);
       replacement->AddInputUse(input);
@@ -4479,7 +4887,12 @@
     phi->set_ssa_temp_index(graph_->alloc_ssa_temp_index());
     phis_.Add(phi);  // Postpone phi insertion until after load forwarding.
 
-    return phi;
+    if (FLAG_trace_load_optimization) {
+      OS::Print("created pending phi %s for %s at B%"Pd"\n",
+                phi->ToCString(),
+                aliased_set_->places()[place_id]->ToCString(),
+                block->block_id());
+    }
   }
 
   // Iterate over basic blocks and replace exposed loads with incoming
@@ -4498,9 +4911,10 @@
 
       for (intptr_t i = 0; i < loads->length(); i++) {
         Definition* load = (*loads)[i];
-        if (!in->Contains(load->expr_id())) continue;  // No incoming value.
+        if (!in->Contains(load->place_id())) continue;  // No incoming value.
 
-        Definition* replacement = MergeIncomingValues(block, load->expr_id());
+        Definition* replacement = MergeIncomingValues(block, load->place_id());
+        ASSERT(replacement != NULL);
 
         // Sets of outgoing values are not linked into use lists so
         // they might contain values that were replace and removed
@@ -4580,16 +4994,117 @@
     return true;
   }
 
+  bool AddPhiPairToWorklist(PhiInstr* a, PhiInstr* b) {
+    // Can't compare two phis from different blocks.
+    if (a->block() != b->block()) {
+      return false;
+    }
+
+    // If a is already in the worklist check if it is being compared to b.
+    // Give up if it is not.
+    if (in_worklist_->Contains(a->ssa_temp_index())) {
+      for (intptr_t i = 0; i < worklist_.length(); i += 2) {
+        if (a == worklist_[i]) {
+          return (b == worklist_[i + 1]);
+        }
+      }
+      UNREACHABLE();
+    }
+
+    worklist_.Add(a);
+    worklist_.Add(b);
+    in_worklist_->Add(a->ssa_temp_index());
+    return true;
+  }
+
+  // Replace the given phi with another if they are equal.
+  // Returns true if succeeds.
+  bool ReplacePhiWith(PhiInstr* phi, PhiInstr* replacement) {
+    ASSERT(phi->InputCount() == replacement->InputCount());
+    ASSERT(phi->block() == replacement->block());
+
+    worklist_.Clear();
+    if (in_worklist_ == NULL) {
+      in_worklist_ = new BitVector(graph_->current_ssa_temp_index());
+    } else {
+      in_worklist_->Clear();
+    }
+
+    // During the comparison worklist contains pairs of phis to be compared.
+    AddPhiPairToWorklist(phi, replacement);
+
+    // Process the worklist. It might grow during each comparison step.
+    for (intptr_t i = 0; i < worklist_.length(); i += 2) {
+      PhiInstr* a = worklist_[i];
+      PhiInstr* b = worklist_[i + 1];
+
+      // Compare phi inputs.
+      for (intptr_t j = 0; j < a->InputCount(); j++) {
+        Definition* inputA = a->InputAt(j)->definition();
+        Definition* inputB = b->InputAt(j)->definition();
+
+        if (inputA != inputB) {
+          // If inputs are unequal by they are phis then add them to
+          // the worklist for recursive comparison.
+          if (inputA->IsPhi() && inputB->IsPhi() &&
+              AddPhiPairToWorklist(inputA->AsPhi(), inputB->AsPhi())) {
+            continue;
+          }
+          return false;  // Not equal.
+        }
+      }
+    }
+
+    // At this point worklist contains pairs of equal phis. Replace the first
+    // phi in the pair with the second.
+    for (intptr_t i = 0; i < worklist_.length(); i += 2) {
+      PhiInstr* a = worklist_[i];
+      PhiInstr* b = worklist_[i + 1];
+      a->ReplaceUsesWith(b);
+      if (a->is_alive()) {
+        a->mark_dead();
+        a->block()->RemovePhi(a);
+      }
+    }
+
+    return true;
+  }
+
+  // Insert the given phi into the graph. Attempt to find an equal one in the
+  // target block first.
+  // Returns true if the phi was inserted and false if it was replaced.
+  bool EmitPhi(PhiInstr* phi) {
+    for (PhiIterator it(phi->block()); !it.Done(); it.Advance()) {
+      if (ReplacePhiWith(phi, it.Current())) {
+        return false;
+      }
+    }
+
+    phi->mark_alive();
+    phi->block()->InsertPhi(phi);
+    return true;
+  }
+
   // Phis have not yet been inserted into the graph but they have uses of
   // their inputs.  Insert the non-redundant ones and clear the input uses
   // of the redundant ones.
   void EmitPhis() {
+    // First eliminate all redundant phis.
     for (intptr_t i = 0; i < phis_.length(); i++) {
       PhiInstr* phi = phis_[i];
-      if (phi->HasUses() && !EliminateRedundantPhi(phi)) {
-        phi->mark_alive();
-        phi->block()->InsertPhi(phi);
-      } else {
+      if (!phi->HasUses() || EliminateRedundantPhi(phi)) {
+        for (intptr_t j = phi->InputCount() - 1; j >= 0; --j) {
+          phi->InputAt(j)->RemoveFromUseList();
+        }
+        phis_[i] = NULL;
+      }
+    }
+
+    // Now emit phis or replace them with equal phis already present in the
+    // graph.
+    for (intptr_t i = 0; i < phis_.length(); i++) {
+      PhiInstr* phi = phis_[i];
+      if ((phi != NULL) && (!phi->HasUses() || !EmitPhi(phi))) {
         for (intptr_t j = phi->InputCount() - 1; j >= 0; --j) {
           phi->InputAt(j)->RemoveFromUseList();
         }
@@ -4599,15 +5114,15 @@
 
   ZoneGrowableArray<Definition*>* CreateBlockOutValues() {
     ZoneGrowableArray<Definition*>* out =
-        new ZoneGrowableArray<Definition*>(aliased_set_->max_expr_id());
-    for (intptr_t i = 0; i < aliased_set_->max_expr_id(); i++) {
+        new ZoneGrowableArray<Definition*>(aliased_set_->max_place_id());
+    for (intptr_t i = 0; i < aliased_set_->max_place_id(); i++) {
       out->Add(NULL);
     }
     return out;
   }
 
   FlowGraph* graph_;
-  DirectChainedHashMap<LoadKeyValueTrait>* map_;
+  DirectChainedHashMap<PointerKeyValueTrait<Place> >* map_;
 
   // Mapping between field offsets in words and expression ids of loads from
   // that offset.
@@ -6059,7 +6574,7 @@
                                  comparison->kind(),
                                  left,
                                  right,
-                                 Array::Handle());
+                                 Object::null_array());
     new_equality_compare->set_ic_data(equality_compare->ic_data());
     new_comparison = new_equality_compare;
   } else {
@@ -6070,7 +6585,7 @@
                               comparison->kind(),
                               left,
                               right,
-                              Array::Handle());
+                              Object::null_array());
     new_relational_op->set_ic_data(relational_op->ic_data());
     new_comparison = new_relational_op;
   }
@@ -6422,6 +6937,13 @@
           OS::Print("discovered allocation sinking candidate: v%"Pd"\n",
                     alloc->ssa_temp_index());
         }
+
+        if (alloc->identity() == AllocateObjectInstr::kAliased) {
+          // Allocation might have been classified as aliased earlier due to
+          // some operations that are now eliminated.
+          alloc->set_identity(AllocateObjectInstr::kNotAliased);
+        }
+
         candidates.Add(alloc);
       }
     }
diff --git a/runtime/vm/handles.h b/runtime/vm/handles.h
index 9f08b7a..7672716 100644
--- a/runtime/vm/handles.h
+++ b/runtime/vm/handles.h
@@ -228,6 +228,7 @@
   friend class HandleScope;
   friend class Dart;
   friend class ObjectStore;
+  friend class Isolate;
   DISALLOW_ALLOCATION();
   DISALLOW_COPY_AND_ASSIGN(Handles);
 };
@@ -338,7 +339,7 @@
 #endif  // defined(DEBUG)
 
 // Macro to start a no handles scope in the code.
-#define NOHANDLESCOPE(isolate)                                                \
+#define NOHANDLESCOPE(isolate)                                                 \
     dart::NoHandleScope no_vm_internal_handles_scope_(isolate);
 
 }  // namespace dart
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index 47fa64b..cdddcd7 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -37,6 +37,7 @@
   FlowGraphPrinter printer(*flow_graph);
   printer.PrintBlocks();
   OS::Print("*** END CFG\n");
+  fflush(stdout);
 }
 
 
@@ -131,8 +132,6 @@
 }
 
 
-
-
 static void PrintICData(BufferFormatter* f, const ICData& ic_data) {
   f->Print(" IC[%"Pd": ", ic_data.NumberOfChecks());
   Function& target = Function::Handle();
@@ -171,6 +170,14 @@
 }
 
 
+const char* Instruction::ToCString() const {
+  char buffer[1024];
+  BufferFormatter f(buffer, sizeof(buffer));
+  PrintTo(&f);
+  return Isolate::Current()->current_zone()->MakeCopyOfString(buffer);
+}
+
+
 void Instruction::PrintTo(BufferFormatter* f) const {
   if (GetDeoptId() != Isolate::kNoDeoptId) {
     f->Print("%s:%"Pd"(", DebugName(), GetDeoptId());
@@ -861,7 +868,7 @@
 
 
 void CheckStackOverflowInstr::PrintOperandsTo(BufferFormatter* f) const {
-  if (in_loop()) f->Print("loop");
+  if (in_loop()) f->Print("depth %"Pd, loop_depth());
 }
 
 
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index 03f94e9..c896e11 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -119,7 +119,7 @@
 }
 
 
-RawArray* CallPattern::ArgumentsDescriptor() {
+RawArray* CallPattern::ClosureArgumentsDescriptor() {
   if (args_desc_.IsNull()) {
     IcData();  // Loading of the ic_data must be decoded first, if not already.
     Register reg;
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index f54328a..98230ae 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -20,7 +20,7 @@
   CallPattern(uword pc, const Code& code);
 
   RawICData* IcData();
-  RawArray* ArgumentsDescriptor();
+  RawArray* ClosureArgumentsDescriptor();
 
   uword TargetAddress() const;
   void SetTargetAddress(uword target_address) const;
diff --git a/runtime/vm/instructions_mips.cc b/runtime/vm/instructions_mips.cc
index 197efd1..1f79afd 100644
--- a/runtime/vm/instructions_mips.cc
+++ b/runtime/vm/instructions_mips.cc
@@ -129,7 +129,7 @@
 }
 
 
-RawArray* CallPattern::ArgumentsDescriptor() {
+RawArray* CallPattern::ClosureArgumentsDescriptor() {
   if (args_desc_.IsNull()) {
     IcData();  // Loading of the ic_data must be decoded first, if not already.
     Register reg;
diff --git a/runtime/vm/instructions_mips.h b/runtime/vm/instructions_mips.h
index f9d7908..fc2ef10 100644
--- a/runtime/vm/instructions_mips.h
+++ b/runtime/vm/instructions_mips.h
@@ -20,7 +20,7 @@
   CallPattern(uword pc, const Code& code);
 
   RawICData* IcData();
-  RawArray* ArgumentsDescriptor();
+  RawArray* ClosureArgumentsDescriptor();
 
   uword TargetAddress() const;
   void SetTargetAddress(uword target_address) const;
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 87e5407..9ade377 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -937,6 +937,16 @@
   phis_->Add(phi);
 }
 
+void JoinEntryInstr::RemovePhi(PhiInstr* phi) {
+  ASSERT(phis_ != NULL);
+  for (intptr_t index = 0; index < phis_->length(); ++index) {
+    if (phi == (*phis_)[index]) {
+      (*phis_)[index] = phis_->Last();
+      phis_->RemoveLast();
+      return;
+    }
+  }
+}
 
 void JoinEntryInstr::RemoveDeadPhis(Definition* replacement) {
   if (phis_ == NULL) return;
@@ -1683,8 +1693,12 @@
 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ICData& call_ic_data = ICData::ZoneHandle(ic_data()->raw());
   if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) {
+    const Array& arguments_descriptor =
+        Array::Handle(ArgumentsDescriptor::New(ArgumentCount(),
+                                               argument_names()));
     call_ic_data = ICData::New(compiler->parsed_function().function(),
                                function_name(),
+                               arguments_descriptor,
                                deopt_id(),
                                checked_argument_count());
   }
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 2285325..f4dc796 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -36,6 +36,7 @@
 // (class-name, function-name, recognized enum, fingerprint).
 // See intrinsifier for fingerprint computation.
 #define RECOGNIZED_LIST(V)                                                     \
+  V(Object, Object., ObjectConstructor, 464682336)                             \
   V(Object, get:_cid, ObjectCid, 732498573)                                    \
   V(_ObjectArray, get:length, ObjectArrayLength, 405297088)                    \
   V(_ImmutableArray, get:length, ImmutableArrayLength, 433698233)              \
@@ -640,7 +641,7 @@
         previous_(NULL),
         next_(NULL),
         env_(NULL),
-        expr_id_(kNoExprId) { }
+        place_id_(kNoPlaceId) { }
 
   virtual Tag tag() const = 0;
 
@@ -731,6 +732,7 @@
   virtual const char* DebugName() const = 0;
 
   // Printing support.
+  const char* ToCString() const;
   virtual void PrintTo(BufferFormatter* f) const;
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
@@ -823,11 +825,10 @@
   // Get the block entry for this instruction.
   virtual BlockEntryInstr* GetBlock() const;
 
-  // Id for load instructions used during load forwarding pass and later in
-  // LICM.
-  intptr_t expr_id() const { return expr_id_; }
-  void set_expr_id(intptr_t expr_id) { expr_id_ = expr_id; }
-  bool HasExprId() const { return expr_id_ != kNoExprId; }
+  // Place identifiers used by the load optimization pass.
+  intptr_t place_id() const { return place_id_; }
+  void set_place_id(intptr_t place_id) { place_id_ = place_id; }
+  bool HasPlaceId() const { return place_id_ != kNoPlaceId; }
 
   // Returns a hash code for use with hash maps.
   virtual intptr_t Hashcode() const;
@@ -927,7 +928,7 @@
   virtual void RawSetInputAt(intptr_t i, Value* value) = 0;
 
   enum {
-    kNoExprId = -1
+    kNoPlaceId = -1
   };
 
   intptr_t deopt_id_;
@@ -935,7 +936,7 @@
   Instruction* previous_;
   Instruction* next_;
   Environment* env_;
-  intptr_t expr_id_;
+  intptr_t place_id_;
 
   DISALLOW_COPY_AND_ASSIGN(Instruction);
 };
@@ -1379,6 +1380,7 @@
   void RemoveDeadPhis(Definition* replacement);
 
   void InsertPhi(PhiInstr* phi);
+  void RemovePhi(PhiInstr* phi);
 
   virtual void PrintTo(BufferFormatter* f) const;
 
@@ -1701,6 +1703,7 @@
   // Phi is alive if it reaches a non-environment use.
   bool is_alive() const { return is_alive_; }
   void mark_alive() { is_alive_ = true; }
+  void mark_dead() { is_alive_ = false; }
 
   virtual Representation RequiredInputRepresentation(intptr_t i) const {
     return representation_;
@@ -2620,7 +2623,7 @@
         checked_argument_count_(checked_argument_count) {
     ASSERT(function_name.IsNotTemporaryScopedHandle());
     ASSERT(!arguments->is_empty());
-    ASSERT(argument_names.IsZoneHandle());
+    ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap());
     ASSERT(Token::IsBinaryOperator(token_kind) ||
            Token::IsPrefixOperator(token_kind) ||
            Token::IsIndexOperator(token_kind) ||
@@ -3069,15 +3072,23 @@
   StaticCallInstr(intptr_t token_pos,
                   const Function& function,
                   const Array& argument_names,
-                  ZoneGrowableArray<PushArgumentInstr*>* arguments)
-      : token_pos_(token_pos),
+                  ZoneGrowableArray<PushArgumentInstr*>* arguments,
+                  const Array& ic_data_array)
+      : ic_data_(GetICData(ic_data_array)),
+        token_pos_(token_pos),
         function_(function),
         argument_names_(argument_names),
         arguments_(arguments),
         result_cid_(kDynamicCid),
         is_known_list_constructor_(false) {
     ASSERT(function.IsZoneHandle());
-    ASSERT(argument_names.IsZoneHandle());
+    ASSERT(argument_names.IsZoneHandle() ||  argument_names.InVMHeap());
+  }
+
+  // ICData for static calls carries call count.
+  const ICData* ic_data() const { return ic_data_; }
+  bool HasICData() const {
+    return (ic_data() != NULL) && !ic_data()->IsNull();
   }
 
   DECLARE_INSTRUCTION(StaticCall)
@@ -3109,6 +3120,7 @@
   virtual bool MayThrow() const { return true; }
 
  private:
+  const ICData* ic_data_;
   const intptr_t token_pos_;
   const Function& function_;
   const Array& argument_names_;
@@ -5920,11 +5932,12 @@
 
 class CheckStackOverflowInstr : public TemplateInstruction<0> {
  public:
-  CheckStackOverflowInstr(intptr_t token_pos, bool in_loop)
-      : token_pos_(token_pos), in_loop_(in_loop) {}
+  CheckStackOverflowInstr(intptr_t token_pos, intptr_t loop_depth)
+      : token_pos_(token_pos), loop_depth_(loop_depth) {}
 
   intptr_t token_pos() const { return token_pos_; }
-  bool in_loop() const { return in_loop_; }
+  bool in_loop() const { return loop_depth_ > 0; }
+  intptr_t loop_depth() const { return loop_depth_; }
 
   DECLARE_INSTRUCTION(CheckStackOverflow)
 
@@ -5940,7 +5953,7 @@
 
  private:
   const intptr_t token_pos_;
-  const bool in_loop_;
+  const intptr_t loop_depth_;
 
   DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr);
 };
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index eacd243..d313806 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -152,6 +152,7 @@
       Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
                                                  argument_names()));
   __ LoadObject(temp_reg, arguments_descriptor);
+  ASSERT(temp_reg == R4);
   compiler->GenerateDartCall(deopt_id(),
                              token_pos(),
                              &StubCode::CallClosureFunctionLabel(),
@@ -385,7 +386,7 @@
                                    token_pos);
   }
   const int kNumberOfArguments = 2;
-  const Array& kNoArgumentNames = Array::Handle();
+  const Array& kNoArgumentNames = Object::null_array();
   const int kNumArgumentsChecked = 2;
 
   Label check_identity;
@@ -407,8 +408,12 @@
       equality_ic_data = original_ic_data.AsUnaryClassChecks();
     }
   } else {
+    const Array& arguments_descriptor =
+        Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments,
+                                               kNoArgumentNames));
     equality_ic_data = ICData::New(compiler->parsed_function().function(),
                                    Symbols::EqualOperator(),
+                                   arguments_descriptor,
                                    deopt_id,
                                    kNumArgumentsChecked);
   }
@@ -545,7 +550,7 @@
       }
     } else {
       const int kNumberOfArguments = 2;
-      const Array& kNoArgumentNames = Array::Handle();
+      const Array& kNoArgumentNames = Object::null_array();
       compiler->GenerateStaticCall(deopt_id,
                                    token_pos,
                                    target,
@@ -926,7 +931,7 @@
     compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
                               R2,  // Class id register.
                               kNumArguments,
-                              Array::Handle(),  // No named arguments.
+                              Object::null_array(),  // No named arguments.
                               deopt,  // Deoptimize target.
                               deopt_id(),
                               token_pos(),
@@ -953,15 +958,19 @@
       relational_ic_data = ic_data()->AsUnaryClassChecks();
     }
   } else {
+    const Array& arguments_descriptor =
+        Array::Handle(ArgumentsDescriptor::New(kNumArguments,
+                                               Object::null_array()));
     relational_ic_data = ICData::New(compiler->parsed_function().function(),
                                      function_name,
+                                     arguments_descriptor,
                                      deopt_id(),
                                      kNumArgsChecked);
   }
   compiler->GenerateInstanceCall(deopt_id(),
                                  token_pos(),
                                  kNumArguments,
-                                 Array::ZoneHandle(),  // No optional arguments.
+                                 Object::null_array(),  // No optional args.
                                  locs(),
                                  relational_ic_data);
 }
@@ -1358,8 +1367,6 @@
     case kTypedDataUint8ArrayCid:
     case kTypedDataUint8ClampedArrayCid:
     case kOneByteStringCid:
-      locs->set_in(2, Location::RegisterOrSmiConstant(value()));
-      break;
     case kTypedDataInt16ArrayCid:
     case kTypedDataUint16ArrayCid:
     case kTypedDataInt32ArrayCid:
@@ -1714,6 +1721,11 @@
 }
 
 
+// When the parser is building an implicit static getter for optimization,
+// it can generate a function body where deoptimization ids do not line up
+// with the unoptimized code.
+//
+// This is safe only so long as LoadStaticFieldInstr cannot deoptimize.
 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Register field = locs()->in(0).reg();
   Register result = locs()->out().reg();
@@ -2151,8 +2163,8 @@
                ShifterOperand(reinterpret_cast<int32_t>(Smi::New(max_right))));
         __ b(deopt, CS);
       }
-      __ SmiUntag(right);
-      __ Lsl(result, left, right);
+      __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP.
+      __ Lsl(result, left, IP);
     }
     return;
   }
@@ -2173,11 +2185,11 @@
       __ cmp(right,
              ShifterOperand(reinterpret_cast<int32_t>(Smi::New(Smi::kBits))));
       __ mov(result, ShifterOperand(0), CS);
-      __ SmiUntag(right, CC);
-      __ Lsl(result, left, right, CC);
+      __ Asr(IP, right, kSmiTagSize, CC);  // SmiUntag right into IP if CC.
+      __ Lsl(result, left, IP, CC);
     } else {
-      __ SmiUntag(right);
-      __ Lsl(result, left, right);
+      __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP.
+      __ Lsl(result, left, IP);
     }
   } else {
     if (right_needs_check) {
@@ -2188,13 +2200,14 @@
     }
     // Left is not a constant.
     // Check if count too large for handling it inlined.
-    __ SmiUntag(right);
-    // Overflow test (preserve left and right);
-    __ Lsl(IP, left, right);
-    __ cmp(left, ShifterOperand(IP, ASR, right));
+    __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP.
+    // Overflow test (preserve left, right, and IP);
+    Register temp = locs.temp(0).reg();
+    __ Lsl(temp, left, IP);
+    __ cmp(left, ShifterOperand(temp, ASR, IP));
     __ b(deopt, NE);  // Overflow.
     // Shift for result now we know there is no overflow.
-    __ Lsl(result, left, right);
+    __ Lsl(result, left, IP);
   }
 }
 
@@ -2205,21 +2218,23 @@
   LocationSummary* summary =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
   if (op_kind() == Token::kTRUNCDIV) {
+    summary->set_in(0, Location::RequiresRegister());
     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_out(Location::RequiresRegister());
     } else {
-      // Both inputs must be writable because they will be untagged.
-      summary->set_in(0, Location::WritableRegister());
-      summary->set_in(1, Location::WritableRegister());
-      summary->set_out(Location::RequiresRegister());
+      summary->set_in(1, Location::RequiresRegister());
     }
+    summary->AddTemp(Location::RequiresRegister());
+    summary->set_out(Location::RequiresRegister());
     return summary;
   }
   summary->set_in(0, Location::RequiresRegister());
   summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+  if (((op_kind() == Token::kSHL) && !is_truncating()) ||
+      (op_kind() == Token::kSHR)) {
+    summary->AddTemp(Location::RequiresRegister());
+  }
   // We make use of 3-operand instructions by not requiring result register
   // to be identical to first input register as on Intel.
   summary->set_out(Location::RequiresRegister());
@@ -2238,7 +2253,7 @@
   Register result = locs()->out().reg();
   Label* deopt = NULL;
   if (CanDeoptimize()) {
-    deopt  = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
+    deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
   }
 
   if (locs()->in(1).IsConstant()) {
@@ -2302,9 +2317,10 @@
         ASSERT(kSmiTagSize == 1);
         __ mov(IP, ShifterOperand(left, ASR, 31));
         ASSERT(shift_count > 1);  // 1, -1 case handled above.
-        __ add(left, left, ShifterOperand(IP, LSR, 32 - shift_count));
+        Register temp = locs()->temp(0).reg();
+        __ add(temp, left, ShifterOperand(IP, LSR, 32 - shift_count));
         ASSERT(shift_count > 0);
-        __ mov(result, ShifterOperand(left, ASR, shift_count));
+        __ mov(result, ShifterOperand(temp, ASR, shift_count));
         if (value < 0) {
           __ rsb(result, result, ShifterOperand(0));
         }
@@ -2397,11 +2413,11 @@
       break;
     }
     case Token::kMUL: {
-      __ SmiUntag(left);
+      __ Asr(IP, left, kSmiTagSize);  // SmiUntag left into IP.
       if (deopt == NULL) {
-        __ mul(result, left, right);
+        __ mul(result, IP, right);
       } else {
-        __ smull(result, IP, left, right);
+        __ smull(result, IP, IP, right);
         // IP: result bits 32..63.
         __ cmp(IP, ShifterOperand(result, ASR, 31));
         __ b(deopt, NE);
@@ -2427,12 +2443,13 @@
       // Handle divide by zero in runtime.
       __ cmp(right, ShifterOperand(0));
       __ b(deopt, EQ);
-      __ SmiUntag(left);
-      __ SmiUntag(right);
+      Register temp = locs()->temp(0).reg();
+      __ Asr(temp, left, kSmiTagSize);  // SmiUntag left into temp.
+      __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP.
       if (!CPUFeatures::integer_division_supported()) {
         UNIMPLEMENTED();
       }
-      __ sdiv(result, left, right);
+      __ sdiv(result, temp, IP);
       // Check the corner case of dividing the 'MIN_SMI' with -1, in which
       // case we cannot tag the result.
       __ CompareImmediate(result, 0x40000000);
@@ -2445,17 +2462,18 @@
         __ CompareImmediate(right, 0);
         __ b(deopt, LT);
       }
-      __ SmiUntag(right);
+      __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP.
       // sarl operation masks the count to 5 bits.
       const intptr_t kCountLimit = 0x1F;
       Range* right_range = this->right()->definition()->range();
       if ((right_range == NULL) ||
           !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
-        __ CompareImmediate(right, kCountLimit);
-        __ LoadImmediate(right, kCountLimit, GT);
+        __ CompareImmediate(IP, kCountLimit);
+        __ LoadImmediate(IP, kCountLimit, GT);
       }
-      __ SmiUntag(left);
-      __ Asr(result, left, right);
+      Register temp = locs()->temp(0).reg();
+      __ Asr(temp, left, kSmiTagSize);  // SmiUntag left into temp.
+      __ Asr(result, temp, IP);
       __ SmiTag(result);
       break;
     }
@@ -3011,7 +3029,7 @@
                                instance_call()->token_pos(),
                                target,
                                kNumberOfArguments,
-                               Array::Handle(),  // No argument names.,
+                               Object::null_array(),  // No argument names.,
                                locs());
   __ Bind(&done);
 }
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 444cd5c..2780369 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -108,17 +108,6 @@
 }
 
 
-LocationSummary* ClosureCallInstr::MakeLocationSummary() const {
-  const intptr_t kNumInputs = 0;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* result =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
-  result->set_out(Location::RegisterLocation(EAX));
-  result->set_temp(0, Location::RegisterLocation(EDX));  // Arg. descriptor.
-  return result;
-}
-
-
 LocationSummary* LoadLocalInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 0;
   return LocationSummary::Make(kNumInputs,
@@ -346,7 +335,7 @@
                                    token_pos);
   }
   const int kNumberOfArguments = 2;
-  const Array& kNoArgumentNames = Array::Handle();
+  const Array& kNoArgumentNames = Object::null_array();
   const int kNumArgumentsChecked = 2;
 
   const Immediate& raw_null =
@@ -368,8 +357,12 @@
       equality_ic_data = original_ic_data.AsUnaryClassChecks();
     }
   } else {
+    const Array& arguments_descriptor =
+        Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments,
+                                               kNoArgumentNames));
     equality_ic_data = ICData::New(compiler->parsed_function().function(),
                                    Symbols::EqualOperator(),
+                                   arguments_descriptor,
                                    deopt_id,
                                    kNumArgumentsChecked);
   }
@@ -496,7 +489,7 @@
       }
     } else {
       const int kNumberOfArguments = 2;
-      const Array& kNoArgumentNames = Array::Handle();
+      const Array& kNoArgumentNames = Object::null_array();
       compiler->GenerateStaticCall(deopt_id,
                                    token_pos,
                                    target,
@@ -985,7 +978,7 @@
     compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
                               EDI,  // Class id register.
                               kNumArguments,
-                              Array::Handle(),  // No named arguments.
+                              Object::null_array(),  // No named arguments.
                               deopt,  // Deoptimize target.
                               deopt_id(),
                               token_pos(),
@@ -1012,15 +1005,19 @@
       relational_ic_data = ic_data()->AsUnaryClassChecks();
     }
   } else {
+    const Array& arguments_descriptor =
+        Array::Handle(ArgumentsDescriptor::New(kNumArguments,
+                                               Object::null_array()));
     relational_ic_data = ICData::New(compiler->parsed_function().function(),
                                      function_name,
+                                     arguments_descriptor,
                                      deopt_id(),
                                      kNumArgsChecked);
   }
   compiler->GenerateInstanceCall(deopt_id(),
                                  token_pos(),
                                  kNumArguments,
-                                 Array::ZoneHandle(),  // No optional arguments.
+                                 Object::null_array(),  // No optional args.
                                  locs(),
                                  relational_ic_data);
 }
@@ -1772,6 +1769,11 @@
 }
 
 
+// When the parser is building an implicit static getter for optimization,
+// it can generate a function body where deoptimization ids do not line up
+// with the unoptimized code.
+//
+// This is safe only so long as LoadStaticFieldInstr cannot deoptimize.
 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Register field = locs()->in(0).reg();
   Register result = locs()->out().reg();
@@ -2147,12 +2149,15 @@
   __ cmpl(ESP,
           Address::Absolute(Isolate::Current()->stack_limit_address()));
   __ j(BELOW_EQUAL, slow_path->entry_label());
-  if (FLAG_use_osr && !compiler->is_optimizing() && in_loop()) {
+  if (compiler->CanOSRFunction() && in_loop()) {
     // In unoptimized code check the usage counter to trigger OSR at loop
-    // stack checks.
+    // stack checks.  Use progressively higher thresholds for more deeply
+    // nested loops to attempt to hit outer loops with OSR when possible.
     __ LoadObject(EDI, compiler->parsed_function().function());
+    intptr_t threshold =
+        FLAG_optimization_counter_threshold * (loop_depth() + 1);
     __ cmpl(FieldAddress(EDI, Function::usage_counter_offset()),
-            Immediate(2 * FLAG_optimization_counter_threshold));
+            Immediate(threshold));
     __ j(GREATER_EQUAL, slow_path->entry_label());
   }
   __ Bind(slow_path->exit_label());
@@ -3723,7 +3728,7 @@
                                instance_call()->token_pos(),
                                target,
                                kNumberOfArguments,
-                               Array::Handle(),  // No argument names.,
+                               Object::null_array(),  // No argument names.,
                                locs());
   __ Bind(&done);
 }
@@ -4643,6 +4648,17 @@
 }
 
 
+LocationSummary* ClosureCallInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 0;
+  const intptr_t kNumTemps = 1;
+  LocationSummary* result =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
+  result->set_out(Location::RegisterLocation(EAX));
+  result->set_temp(0, Location::RegisterLocation(EDX));  // Arg. descriptor.
+  return result;
+}
+
+
 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   // The arguments to the stub include the closure, as does the arguments
   // descriptor.
@@ -4652,6 +4668,7 @@
       Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
                                                  argument_names()));
   __ LoadObject(temp_reg, arguments_descriptor);
+  ASSERT(temp_reg == EDX);
   compiler->GenerateDartCall(deopt_id(),
                              token_pos(),
                              &StubCode::CallClosureFunctionLabel(),
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 813378d..bbb4f5e 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -153,6 +153,7 @@
   const Array& arguments_descriptor =
       Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
                                                  argument_names()));
+  ASSERT(temp_reg == S4);
   __ LoadObject(temp_reg, arguments_descriptor);
   compiler->GenerateDartCall(deopt_id(),
                              token_pos(),
@@ -383,7 +384,7 @@
                                    token_pos);
   }
   const int kNumberOfArguments = 2;
-  const Array& kNoArgumentNames = Array::Handle();
+  const Array& kNoArgumentNames = Object::null_array();
   const int kNumArgumentsChecked = 2;
 
   __ TraceSimMsg("EmitEqualityAsInstanceCall");
@@ -406,8 +407,12 @@
       equality_ic_data = original_ic_data.AsUnaryClassChecks();
     }
   } else {
+    const Array& arguments_descriptor =
+        Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments,
+                                               kNoArgumentNames));
     equality_ic_data = ICData::New(compiler->parsed_function().function(),
                                    Symbols::EqualOperator(),
+                                   arguments_descriptor,
                                    deopt_id,
                                    kNumArgumentsChecked);
   }
@@ -575,7 +580,7 @@
       }
     } else {
       const int kNumberOfArguments = 2;
-      const Array& kNoArgumentNames = Array::Handle();
+      const Array& kNoArgumentNames = Object::null_array();
       compiler->GenerateStaticCall(deopt_id,
                                    token_pos,
                                    target,
@@ -985,7 +990,7 @@
     compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
                               A2,  // Class id register.
                               kNumArguments,
-                              Array::Handle(),  // No named arguments.
+                              Object::null_array(),  // No named arguments.
                               deopt,  // Deoptimize target.
                               deopt_id(),
                               token_pos(),
@@ -1012,15 +1017,19 @@
       relational_ic_data = ic_data()->AsUnaryClassChecks();
     }
   } else {
+    const Array& arguments_descriptor =
+        Array::Handle(ArgumentsDescriptor::New(kNumArguments,
+                                               Object::null_array()));
     relational_ic_data = ICData::New(compiler->parsed_function().function(),
                                      function_name,
+                                     arguments_descriptor,
                                      deopt_id(),
                                      kNumArgsChecked);
   }
   compiler->GenerateInstanceCall(deopt_id(),
                                  token_pos(),
                                  kNumArguments,
-                                 Array::ZoneHandle(),  // No optional arguments.
+                                 Object::null_array(),  // No optional args.
                                  locs(),
                                  relational_ic_data);
 }
@@ -1416,8 +1425,6 @@
     case kTypedDataUint8ArrayCid:
     case kTypedDataUint8ClampedArrayCid:
     case kOneByteStringCid:
-      locs->set_in(2, Location::RegisterOrSmiConstant(value()));
-      break;
     case kTypedDataInt16ArrayCid:
     case kTypedDataUint16ArrayCid:
     case kTypedDataInt32ArrayCid:
@@ -1559,7 +1566,15 @@
       break;
     }
     case kTypedDataFloat32ArrayCid:
+      // Convert to single precision.
+      __ cvtsd(STMP1, locs()->in(2).fpu_reg());
+      // Store.
+      __ swc1(STMP1, element_address);
+      break;
     case kTypedDataFloat64ArrayCid:
+      __ StoreDToOffset(locs()->in(2).fpu_reg(), index.reg(),
+          FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
+      break;
     case kTypedDataFloat32x4ArrayCid:
       UNIMPLEMENTED();
       break;
@@ -1773,6 +1788,11 @@
 }
 
 
+// When the parser is building an implicit static getter for optimization,
+// it can generate a function body where deoptimization ids do not line up
+// with the unoptimized code.
+//
+// This is safe only so long as LoadStaticFieldInstr cannot deoptimize.
 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   __ TraceSimMsg("LoadStaticFieldInstr");
   Register field = locs()->in(0).reg();
@@ -2243,8 +2263,8 @@
         __ BranchUnsignedGreaterEqual(
             right, reinterpret_cast<int32_t>(Smi::New(max_right)), deopt);
       }
-      __ SmiUntag(right);
-      __ sllv(result, left, right);
+      __ sra(TMP, right, kSmiTagMask);  // SmiUntag right into TMP.
+      __ sllv(result, left, TMP);
     }
     return;
   }
@@ -2271,8 +2291,8 @@
       // result = right < kBits ? left << right : result.
       __ movn(result, TMP1, CMPRES);
     } else {
-      __ SmiUntag(right);
-      __ sllv(result, left, right);
+      __ sra(TMP, right, kSmiTagSize);
+      __ sllv(result, left, TMP);
     }
   } else {
     if (right_needs_check) {
@@ -2282,13 +2302,14 @@
     }
     // Left is not a constant.
     // Check if count too large for handling it inlined.
-    __ SmiUntag(right);
-    // Overflow test (preserve left and right);
-    __ sllv(TMP1, left, right);
-    __ srav(TMP1, TMP1, right);
-    __ bne(TMP1, left, deopt);  // Overflow.
+    __ sra(TMP, right, kSmiTagSize);  // SmiUntag right into TMP.
+    // Overflow test (preserve left, right, and TMP);
+    Register temp = locs.temp(0).reg();
+    __ sllv(temp, left, TMP);
+    __ srav(temp, temp, TMP);
+    __ bne(temp, left, deopt);  // Overflow.
     // Shift for result now we know there is no overflow.
-    __ sllv(result, left, right);
+    __ sll(result, left, TMP);
   }
 }
 
@@ -2299,22 +2320,23 @@
   LocationSummary* summary =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
   if (op_kind() == Token::kTRUNCDIV) {
+    summary->set_in(0, Location::RequiresRegister());
     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_out(Location::RequiresRegister());
     } else {
-      // Both inputs must be writable because they will be untagged.
-      summary->set_in(0, Location::WritableRegister());
-      summary->set_in(1, Location::WritableRegister());
-      summary->set_out(Location::RequiresRegister());
+      summary->set_in(1, Location::RequiresRegister());
     }
+    summary->AddTemp(Location::RequiresRegister());
+    summary->set_out(Location::RequiresRegister());
     return summary;
   }
   summary->set_in(0, Location::RequiresRegister());
   summary->set_in(1, Location::RegisterOrSmiConstant(right()));
-  if (op_kind() == Token::kADD) {
+  if (((op_kind() == Token::kSHL) && !is_truncating()) ||
+      (op_kind() == Token::kSHR)) {
+    summary->AddTemp(Location::RequiresRegister());
+  } else if (op_kind() == Token::kADD) {
     // Need an extra temp for the overflow detection code.
     summary->set_temp(0, Location::RequiresRegister());
   }
@@ -2337,7 +2359,7 @@
   Register result = locs()->out().reg();
   Label* deopt = NULL;
   if (CanDeoptimize()) {
-    deopt  = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
+    deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
   }
 
   if (locs()->in(1).IsConstant()) {
@@ -2411,10 +2433,11 @@
         ASSERT(kSmiTagSize == 1);
         __ sra(TMP, left, 31);
         ASSERT(shift_count > 1);  // 1, -1 case handled above.
-        __ sll(TMP, TMP, 32 - shift_count);
-        __ addu(left, left, TMP);
+        Register temp = locs()->temp(0).reg();
+        __ srl(TMP, TMP, 32 - shift_count);
+        __ addu(temp, left, TMP);
         ASSERT(shift_count > 0);
-        __ sra(result, left, shift_count);
+        __ sra(result, temp, shift_count);
         if (value < 0) {
           __ subu(result, ZR, result);
         }
@@ -2509,8 +2532,8 @@
     }
     case Token::kMUL: {
       __ TraceSimMsg("kMUL");
-      __ SmiUntag(left);
-      __ mult(left, right);
+      __ sra(TMP, left, kSmiTagSize);
+      __ mult(TMP, right);
       __ mflo(result);
       if (deopt != NULL) {
         __ mfhi(TMP1);
@@ -2537,18 +2560,36 @@
     case Token::kTRUNCDIV: {
       // Handle divide by zero in runtime.
       __ beq(right, ZR, deopt);
-      __ SmiUntag(left);
-      __ SmiUntag(right);
-      __ div(left, right);
+      Register temp = locs()->temp(0).reg();
+      __ sra(temp, left, kSmiTagSize);  // SmiUntag left into temp.
+      __ sra(TMP, right, kSmiTagSize);  // SmiUntag right into TMP.
+      __ div(temp, TMP);
       __ mflo(result);
       // Check the corner case of dividing the 'MIN_SMI' with -1, in which
       // case we cannot tag the result.
-      __ BranchEqual(V0, 0x40000000, deopt);
+      __ BranchEqual(result, 0x40000000, deopt);
       __ SmiTag(result);
       break;
     }
     case Token::kSHR: {
-      UNIMPLEMENTED();
+      if (CanDeoptimize()) {
+        __ bltz(right, deopt);
+      }
+      __ sra(TMP, right, kSmiTagSize);  // SmiUntag right into TMP.
+      // sra operation masks the count to 5 bits.
+      const intptr_t kCountLimit = 0x1F;
+      Range* right_range = this->right()->definition()->range();
+      if ((right_range == NULL) ||
+          !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
+        Label ok;
+        __ BranchSignedLessEqual(TMP, kCountLimit, &ok);
+        __ LoadImmediate(TMP, kCountLimit);
+        __ Bind(&ok);
+      }
+      Register temp = locs()->temp(0).reg();
+      __ sra(temp, left, kSmiTagSize);  // SmiUntag left into temp.
+      __ srav(result, temp, TMP);
+      __ SmiTag(result);
       break;
     }
     case Token::kDIV: {
@@ -2996,13 +3037,18 @@
 
 
 LocationSummary* MathSqrtInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_out(Location::RequiresFpuRegister());
+  return summary;
 }
 
 
 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  __ sqrtd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg());
 }
 
 
@@ -3072,13 +3118,28 @@
 
 
 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* result = new LocationSummary(
+      kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  result->set_in(0, Location::RequiresFpuRegister());
+  result->set_out(Location::RequiresRegister());
+  return result;
 }
 
 
 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi);
+  Register result = locs()->out().reg();
+  DRegister value = locs()->in(0).fpu_reg();
+  __ cvtwd(STMP1, value);
+  __ mfc1(result, STMP1);
+
+  // Check for overflow and that it fits into Smi.
+  __ LoadImmediate(TMP, 0xC0000000);
+  __ subu(CMPRES, result, TMP);
+  __ bltz(CMPRES, deopt);
+  __ SmiTag(result);
 }
 
 
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index a55f175..16cb424 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -274,17 +274,6 @@
 }
 
 
-LocationSummary* ClosureCallInstr::MakeLocationSummary() const {
-  const intptr_t kNumInputs = 0;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* result =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
-  result->set_out(Location::RegisterLocation(RAX));
-  result->set_temp(0, Location::RegisterLocation(R10));  // Arg. descriptor.
-  return result;
-}
-
-
 LocationSummary* LoadLocalInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 0;
   return LocationSummary::Make(kNumInputs,
@@ -502,7 +491,7 @@
                                    token_pos);
   }
   const int kNumberOfArguments = 2;
-  const Array& kNoArgumentNames = Array::Handle();
+  const Array& kNoArgumentNames = Object::null_array();
   const int kNumArgumentsChecked = 2;
 
   const Immediate& raw_null =
@@ -524,8 +513,12 @@
       equality_ic_data = original_ic_data.AsUnaryClassChecks();
     }
   } else {
+    const Array& arguments_descriptor =
+        Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments,
+                                               kNoArgumentNames));
     equality_ic_data = ICData::New(compiler->parsed_function().function(),
                                    Symbols::EqualOperator(),
+                                   arguments_descriptor,
                                    deopt_id,
                                    kNumArgumentsChecked);
   }
@@ -653,7 +646,7 @@
       }
     } else {
       const int kNumberOfArguments = 2;
-      const Array& kNoArgumentNames = Array::Handle();
+      const Array& kNoArgumentNames = Object::null_array();
       compiler->GenerateStaticCall(deopt_id,
                                    token_pos,
                                    target,
@@ -1013,7 +1006,7 @@
     compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
                               RDI,  // Class id register.
                               kNumArguments,
-                              Array::Handle(),  // No named arguments.
+                              Object::null_array(),  // No named arguments.
                               deopt,  // Deoptimize target.
                               deopt_id(),
                               token_pos(),
@@ -1040,15 +1033,19 @@
       relational_ic_data = ic_data()->AsUnaryClassChecks();
     }
   } else {
+    const Array& arguments_descriptor =
+        Array::Handle(ArgumentsDescriptor::New(kNumArguments,
+                                               Object::null_array()));
     relational_ic_data = ICData::New(compiler->parsed_function().function(),
                                      function_name,
+                                     arguments_descriptor,
                                      deopt_id(),
                                      kNumArgsChecked);
   }
   compiler->GenerateInstanceCall(deopt_id(),
                                  token_pos(),
                                  kNumArguments,
-                                 Array::ZoneHandle(),  // No optional arguments.
+                                 Object::null_array(),  // No optional args.
                                  locs(),
                                  relational_ic_data);
 }
@@ -1754,6 +1751,11 @@
 }
 
 
+// When the parser is building an implicit static getter for optimization,
+// it can generate a function body where deoptimization ids do not line up
+// with the unoptimized code.
+//
+// This is safe only so long as LoadStaticFieldInstr cannot deoptimize.
 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Register field = locs()->in(0).reg();
   Register result = locs()->out().reg();
@@ -2132,12 +2134,15 @@
   __ movq(temp, Immediate(Isolate::Current()->stack_limit_address()));
   __ cmpq(RSP, Address(temp, 0));
   __ j(BELOW_EQUAL, slow_path->entry_label());
-  if (FLAG_use_osr && !compiler->is_optimizing() && in_loop()) {
+  if (compiler->CanOSRFunction() && in_loop()) {
     // In unoptimized code check the usage counter to trigger OSR at loop
-    // stack checks.
+    // stack checks.  Use progressively higher thresholds for more deeply
+    // nested loops to attempt to hit outer loops with OSR when possible.
     __ LoadObject(temp, compiler->parsed_function().function());
+    intptr_t threshold =
+        FLAG_optimization_counter_threshold * (loop_depth() + 1);
     __ cmpq(FieldAddress(temp, Function::usage_counter_offset()),
-            Immediate(2 * FLAG_optimization_counter_threshold));
+            Immediate(threshold));
     __ j(GREATER_EQUAL, slow_path->entry_label());
   }
   __ Bind(slow_path->exit_label());
@@ -3786,7 +3791,7 @@
                                instance_call()->token_pos(),
                                target,
                                kNumberOfArguments,
-                               Array::Handle(),  // No argument names.
+                               Object::null_array(),  // No argument names.
                                locs());
   __ Bind(&done);
 }
@@ -4313,6 +4318,17 @@
 }
 
 
+LocationSummary* ClosureCallInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 0;
+  const intptr_t kNumTemps = 1;
+  LocationSummary* result =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
+  result->set_out(Location::RegisterLocation(RAX));
+  result->set_temp(0, Location::RegisterLocation(R10));  // Arg. descriptor.
+  return result;
+}
+
+
 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   // The arguments to the stub include the closure, as does the arguments
   // descriptor.
@@ -4322,6 +4338,7 @@
       Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
                                                  argument_names()));
   __ LoadObject(temp_reg, arguments_descriptor);
+  ASSERT(temp_reg == R10);
   compiler->GenerateDartCall(deopt_id(),
                              token_pos(),
                              &StubCode::CallClosureFunctionLabel(),
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 1e2dd8b..18b4744 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -243,7 +243,7 @@
   __ StoreIntoObject(R0,
                      FieldAddress(R1, Array::data_offset()),
                      R2);
-  // Caller is responsible of preserving the value if necessary.
+  // Caller is responsible for preserving the value if necessary.
   __ Ret();
   __ Bind(&fall_through);
   return false;
@@ -869,23 +869,23 @@
   __ bx(LR, EQ);
 
   // Arguments are Smi but the shift produced an overflow to Mint.
-  __ CompareImmediate(R6, 0);
+  __ CompareImmediate(R1, 0);
   __ b(&fall_through, LT);
-  __ SmiUntag(R6);
+  __ SmiUntag(R1);
 
-  // Pull off high bits that will be shifted off of R6 by making a mask
-  // ((1 << R0) - 1), shifting it to the left, masking R6, then shifting back.
-  // high bits = (((1 << R0) - 1) << (32 - R0)) & R6) >> (32 - R0)
-  // lo bits = R6 << R0
+  // Pull off high bits that will be shifted off of R1 by making a mask
+  // ((1 << R0) - 1), shifting it to the left, masking R1, then shifting back.
+  // high bits = (((1 << R0) - 1) << (32 - R0)) & R1) >> (32 - R0)
+  // lo bits = R1 << R0
   __ LoadImmediate(R7, 1);
   __ mov(R7, ShifterOperand(R7, LSL, R0));  // R7 <- 1 << R0
   __ sub(R7, R7, ShifterOperand(1));  // R7 <- R7 - 1
   __ rsb(R8, R0, ShifterOperand(32));  // R8 <- 32 - R0
   __ mov(R7, ShifterOperand(R7, LSL, R8));  // R7 <- R7 << R8
-  __ and_(R7, R6, ShifterOperand(R7));  // R7 <- R7 & R6
+  __ and_(R7, R1, ShifterOperand(R7));  // R7 <- R7 & R1
   __ mov(R7, ShifterOperand(R7, LSR, R8));  // R7 <- R7 >> R8
-  // Now R7 has the bits that fall off of R6 on a left shift.
-  __ mov(R1, ShifterOperand(R6, LSL, R0));  // R1 gets the low bits.
+  // Now R7 has the bits that fall off of R1 on a left shift.
+  __ mov(R1, ShifterOperand(R1, LSL, R0));  // R1 gets the low bits.
 
   const Class& mint_class = Class::Handle(
       Isolate::Current()->object_store()->mint_class());
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index 4f8588b..2627738 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -204,8 +204,8 @@
     // Null value is valid for any type.
     __ LoadImmediate(T7, reinterpret_cast<int32_t>(Object::null()));
     __ beq(T2, T7, &checked_ok);
-    __ delay_slot()->lw(T1, Address(SP, 2 * kWordSize));  // Array.
 
+    __ lw(T1, Address(SP, 2 * kWordSize));  // Array.
     __ lw(T1, FieldAddress(T1, type_args_field_offset));
 
     // T1: Type arguments of array.
@@ -232,8 +232,8 @@
   __ andi(CMPRES, T1, Immediate(kSmiTagMask));
   // Index not Smi.
   __ bne(CMPRES, ZR, &fall_through);
-  __ delay_slot()->lw(T0, Address(SP, 2 * kWordSize));  // Array.
 
+  __ lw(T0, Address(SP, 2 * kWordSize));  // Array.
   // Range check.
   __ lw(T3, FieldAddress(T0, Array::length_offset()));  // Array length.
   // Runtime throws exception.
@@ -248,7 +248,7 @@
   __ StoreIntoObject(T0,
                      FieldAddress(T1, Array::data_offset()),
                      T2);
-  // Caller is responsible of preserving the value if necessary.
+  // Caller is responsible for preserving the value if necessary.
   __ Ret();
   __ Bind(&fall_through);
   return false;
@@ -864,10 +864,9 @@
 
   // Check for overflow by shifting left and shifting back arithmetically.
   // If the result is different from the original, there was overflow.
-  __ mov(T2, T1);
-  __ sllv(T1, T1, T0);
-  __ srlv(T1, T1, T0);
-  __ bne(T1, T2, &overflow);
+  __ sllv(TMP, T1, T0);
+  __ srav(TMP, TMP, T0);
+  __ bne(TMP, T1, &overflow);
 
   // No overflow, result in V0.
   __ Ret();
@@ -875,23 +874,23 @@
 
   __ Bind(&overflow);
   // Arguments are Smi but the shift produced an overflow to Mint.
-  __ bltz(T2, &fall_through);
-  __ SmiUntag(T2);
+  __ bltz(T1, &fall_through);
+  __ SmiUntag(T1);
 
-  // Pull off high bits that will be shifted off of T2 by making a mask
-  // ((1 << T0) - 1), shifting it to the right, masking T2, then shifting back.
-  // high bits = (((1 << T0) - 1) << (32 - T0)) & T2) >> (32 - T0)
-  // lo bits = T2 << T0
+  // Pull off high bits that will be shifted off of T1 by making a mask
+  // ((1 << T0) - 1), shifting it to the right, masking T1, then shifting back.
+  // high bits = (((1 << T0) - 1) << (32 - T0)) & T1) >> (32 - T0)
+  // lo bits = T1 << T0
   __ LoadImmediate(T3, 1);
   __ sllv(T3, T3, T0);  // T3 <- T3 << T0
   __ addiu(T3, T3, Immediate(-1));  // T3 <- T3 - 1
-  __ addu(T4, ZR, T0);  // T4 <- -T0
+  __ subu(T4, ZR, T0);  // T4 <- -T0
   __ addiu(T4, T4, Immediate(32));  // T4 <- 32 - T0
   __ sllv(T3, T3, T4);  // T3 <- T3 << T4
-  __ and_(T3, T3, T2);  // T3 <- T3 & T2
+  __ and_(T3, T3, T1);  // T3 <- T3 & T1
   __ srlv(T3, T3, T4);  // T3 <- T3 >> T4
-  // Now T3 has the bits that fall off of T2 on a left shift.
-  __ sllv(T0, T2, T0);  // T0 gets low bits.
+  // Now T3 has the bits that fall off of T1 on a left shift.
+  __ sllv(T0, T1, T0);  // T0 gets low bits.
 
   const Class& mint_class = Class::Handle(
       Isolate::Current()->object_store()->mint_class());
@@ -1338,16 +1337,15 @@
 bool Intrinsifier::Double_getIsNegative(Assembler* assembler) {
   Label is_false, is_true, is_zero;
   __ lw(T0, Address(SP, 0 * kWordSize));
-  __ lwc1(F0, FieldAddress(T0, Double::value_offset()));
-  __ lwc1(F1, FieldAddress(T0, Double::value_offset() + kWordSize));
+  __ LoadDFromOffset(D0, T0, Double::value_offset() - kHeapObjectTag);
 
   __ cund(D0, D0);
   __ bc1t(&is_false);  // NaN -> false.
 
+  __ LoadImmediate(D1, 0.0);
   __ ceqd(D0, D1);
   __ bc1t(&is_zero);  // Check for negative zero.
 
-  __ LoadImmediate(D1, 0.0);
   __ coled(D1, D0);
   __ bc1t(&is_false);  // >= 0 -> false.
 
@@ -1372,14 +1370,17 @@
 
 bool Intrinsifier::Double_toInt(Assembler* assembler) {
   __ lw(T0, Address(SP, 0 * kWordSize));
-  __ lwc1(F0, FieldAddress(T0, Double::value_offset()));
-  __ lwc1(F1, FieldAddress(T0, Double::value_offset() + kWordSize));
+  __ LoadDFromOffset(D0, T0, Double::value_offset() - kHeapObjectTag);
+
   __ cvtwd(F2, D0);
   __ mfc1(V0, F2);
+
   // Overflow is signaled with minint.
   Label fall_through;
   // Check for overflow and that it fits into Smi.
-  __ BranchSignedLess(V0, 0xC0000000, &fall_through);
+  __ LoadImmediate(TMP, 0xC0000000);
+  __ subu(CMPRES, V0, TMP);
+  __ bltz(CMPRES, &fall_through);
   __ Ret();
   __ delay_slot()->SmiTag(V0);
   __ Bind(&fall_through);
@@ -1448,24 +1449,25 @@
   __ lw(T1, FieldAddress(T0, state_field.Offset()));  // Field '_state'.
 
   // Addresses of _state[0] and _state[1].
-  const int64_t disp_0 =
-      FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid);
+  const Address& addr_0 = FieldAddress(T1,
+      FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid));
 
-  const int64_t disp_1 =
+  const Address& addr_1 = FieldAddress(T1,
       FlowGraphCompiler::ElementSizeFor(kTypedDataUint32ArrayCid) +
-      FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid);
+      FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid));
+
   __ LoadImmediate(T0, a_int32_value);
-  __ lw(T2, FieldAddress(T1, disp_0));
-  __ lw(T3, FieldAddress(T1, disp_1));
+  __ lw(T2, addr_0);
+  __ lw(T3, addr_1);
   __ sra(T6, T3, 31);  // Sign extend T3 into T6.
   __ mtlo(T3);
   __ mthi(T6);  // HI:LO <- T6:T3
   // 64-bit multiply and accumulate into T6:T3.
-  __ madd(T0, T2);  // HI:LO <- HI:LO + T0 * T3.
+  __ madd(T0, T2);  // HI:LO <- HI:LO + T0 * T2.
   __ mflo(T3);
   __ mfhi(T6);
-  __ sw(T3, FieldAddress(T1, disp_0));
-  __ sw(T6, FieldAddress(T1, disp_1));
+  __ sw(T3, addr_0);
+  __ sw(T6, addr_1);
   __ Ret();
   return true;
 }
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 87a6d81..0e95ac0 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -371,6 +371,9 @@
 }
 
 
+#define REUSABLE_HANDLE_INITIALIZERS(object)                                   \
+  object##_handle_(NULL),
+
 Isolate::Isolate()
     : store_buffer_(),
       message_notify_callback_(NULL),
@@ -399,6 +402,7 @@
       running_state_(kIsolateWaiting),
       gc_prologue_callbacks_(),
       gc_epilogue_callbacks_(),
+      defer_finalization_count_(0),
       deopt_cpu_registers_copy_(NULL),
       deopt_fpu_registers_copy_(NULL),
       deopt_frame_copy_(NULL),
@@ -409,11 +413,14 @@
       deferred_objects_(NULL),
       stacktrace_(NULL),
       stack_frame_index_(-1),
-      object_histogram_(NULL) {
+      object_histogram_(NULL),
+      REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
+      reusable_handles_() {
   if (FLAG_print_object_histogram && (Dart::vm_isolate() != NULL)) {
     object_histogram_ = new ObjectHistogram(this);
   }
 }
+#undef REUSABLE_HANDLE_INITIALIZERS
 
 
 Isolate::~Isolate() {
@@ -461,6 +468,13 @@
   // the current isolate.
   SetCurrent(result);
 
+  // Setup the isolate specific resuable handles.
+#define REUSABLE_HANDLE_ALLOCATION(object)                                     \
+  result->object##_handle_ = result->AllocateReusableHandle<object>();         \
+
+  REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_ALLOCATION)
+#undef REUSABLE_HANDLE_ALLOCATION
+
   // Setup the isolate message handler.
   MessageHandler* handler = new IsolateMessageHandler(result);
   ASSERT(handler != NULL);
@@ -825,6 +839,9 @@
   // Visit objects in zones.
   current_zone()->VisitObjectPointers(visitor);
 
+  // Visit objects in isolate specific handles area.
+  reusable_handles_.VisitObjectPointers(visitor);
+
   // Iterate over all the stack frames and visit objects on the stack.
   StackFrameIterator frames_iterator(validate_frames);
   StackFrame* frame = frames_iterator.NextFrame();
@@ -1050,6 +1067,14 @@
 }
 
 
+template<class T>
+T* Isolate::AllocateReusableHandle() {
+  T* handle = reinterpret_cast<T*>(reusable_handles_.AllocateScopedHandle());
+  T::initializeHandle(handle, T::null());
+  return handle;
+}
+
+
 static void FillDeferredSlots(DeferredSlot** slot_list) {
   DeferredSlot* slot = *slot_list;
   *slot_list = NULL;
@@ -1075,6 +1100,16 @@
 }
 
 
+void ReusableHandleScope::ResetHandles() {
+#define CLEAR_REUSABLE_HANDLE(object)                                          \
+  if (!object##Handle().IsNull()) {                                            \
+    object##Handle().raw_ = Object::null();                                    \
+  }
+
+  REUSABLE_HANDLE_LIST(CLEAR_REUSABLE_HANDLE);
+}
+
+
 static char* GetRootScriptUri(Isolate* isolate) {
   const Library& library =
       Library::Handle(isolate->object_store()->root_library());
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index a2e37c5..67ee82b 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -11,6 +11,7 @@
 #include "vm/base_isolate.h"
 #include "vm/class_table.h"
 #include "vm/gc_callbacks.h"
+#include "vm/handles.h"
 #include "vm/megamorphic_cache_table.h"
 #include "vm/store_buffer.h"
 #include "vm/timer.h"
@@ -18,9 +19,13 @@
 namespace dart {
 
 // Forward declarations.
+class AbstractType;
 class ApiState;
+class Array;
+class Class;
 class CodeIndexTable;
 class Debugger;
+class Field;
 class Function;
 class HandleScope;
 class HandleVisitor;
@@ -30,6 +35,7 @@
 class LongJump;
 class MessageHandler;
 class Mutex;
+class Object;
 class ObjectPointerVisitor;
 class ObjectStore;
 class RawInstance;
@@ -40,12 +46,14 @@
 class RawObject;
 class RawInteger;
 class RawError;
+class RawFloat32x4;
+class RawUint32x4;
 class Simulator;
 class StackResource;
 class StackZone;
 class StubCode;
-class RawFloat32x4;
-class RawUint32x4;
+class TypeArguments;
+class TypeParameter;
 class ObjectHistogram;
 
 
@@ -217,6 +225,17 @@
   DISALLOW_COPY_AND_ASSIGN(DeferredObject);
 };
 
+#define REUSABLE_HANDLE_LIST(V)                                                \
+  V(Object)                                                                    \
+  V(Array)                                                                     \
+  V(String)                                                                    \
+  V(Instance)                                                                  \
+  V(Function)                                                                  \
+  V(Field)                                                                     \
+  V(Class)                                                                     \
+  V(AbstractType)                                                              \
+  V(TypeParameter)                                                             \
+  V(TypeArguments)                                                             \
 
 class Isolate : public BaseIsolate {
  public:
@@ -583,6 +602,21 @@
 
   static char* GetStatus(const char* request);
 
+  intptr_t BlockClassFinalization() {
+    ASSERT(defer_finalization_count_ >= 0);
+    return defer_finalization_count_++;
+  }
+
+  intptr_t UnblockClassFinalization() {
+    ASSERT(defer_finalization_count_ > 0);
+    return defer_finalization_count_--;
+  }
+
+  bool AllowClassFinalization() {
+    ASSERT(defer_finalization_count_ >= 0);
+    return defer_finalization_count_ == 0;
+  }
+
  private:
   Isolate();
 
@@ -595,6 +629,7 @@
   char* GetStatusStacktrace();
   char* GetStatusStackFrame(intptr_t index);
   char* DoStacktraceInterrupt(Dart_IsolateInterruptCallback cb);
+  template<class T> T* AllocateReusableHandle();
 
   static ThreadLocalKey isolate_key;
   StoreBuffer store_buffer_;
@@ -626,6 +661,7 @@
   IsolateRunState running_state_;
   GcPrologueCallbacks gc_prologue_callbacks_;
   GcEpilogueCallbacks gc_epilogue_callbacks_;
+  intptr_t defer_finalization_count_;
 
   // Deoptimization support.
   intptr_t* deopt_cpu_registers_copy_;
@@ -643,6 +679,14 @@
   intptr_t stack_frame_index_;
   ObjectHistogram* object_histogram_;
 
+  // Reusable handles support.
+#define REUSABLE_HANDLE_FIELDS(object)                                         \
+  object* object##_handle_;                                                    \
+
+  REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_FIELDS)
+#undef REUSABLE_HANDLE_FIELDS
+  VMHandles reusable_handles_;
+
   static Dart_IsolateCreateCallback create_callback_;
   static Dart_IsolateInterruptCallback interrupt_callback_;
   static Dart_IsolateUnhandledExceptionCallback unhandled_exception_callback_;
@@ -653,9 +697,85 @@
   static Dart_FileCloseCallback file_close_callback_;
   static Dart_IsolateInterruptCallback vmstats_callback_;
 
+  friend class ReusableHandleScope;
   DISALLOW_COPY_AND_ASSIGN(Isolate);
 };
 
+// The class ReusableHandleScope is used in regions of the
+// virtual machine where isolate specific reusable handles are used.
+// This class asserts that we do not add code that will result in recursive
+// uses of reusable handles.
+// It is used as follows:
+// {
+//   ReusableHandleScope reused_handles(isolate);
+//   ....
+//   .....
+//   code that uses isolate specific reusable handles.
+//   Array& funcs = reused_handles.ArrayHandle();
+//   ....
+// }
+#if defined(DEBUG)
+class ReusableHandleScope : public StackResource {
+ public:
+  explicit ReusableHandleScope(Isolate* isolate)
+      : StackResource(isolate), isolate_(isolate) {
+    ASSERT(!isolate->reusable_handle_scope_active());
+    isolate->set_reusable_handle_scope_active(true);
+  }
+  ReusableHandleScope()
+      : StackResource(Isolate::Current()), isolate_(Isolate::Current()) {
+    ASSERT(!isolate()->reusable_handle_scope_active());
+    isolate()->set_reusable_handle_scope_active(true);
+  }
+  ~ReusableHandleScope() {
+    ASSERT(isolate()->reusable_handle_scope_active());
+    isolate()->set_reusable_handle_scope_active(false);
+    ResetHandles();
+  }
+
+#define REUSABLE_HANDLE_ACCESSORS(object)                                      \
+  object& object##Handle() {                                                   \
+    ASSERT(isolate_->object##_handle_ != NULL);                                \
+    return *isolate_->object##_handle_;                                        \
+  }                                                                            \
+
+  REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_ACCESSORS)
+#undef REUSABLE_HANDLE_ACCESSORS
+
+ private:
+  void ResetHandles();
+  Isolate* isolate_;
+  DISALLOW_COPY_AND_ASSIGN(ReusableHandleScope);
+};
+#else
+class ReusableHandleScope : public ValueObject {
+ public:
+  explicit ReusableHandleScope(Isolate* isolate) : isolate_(isolate) {
+  }
+  ReusableHandleScope() : isolate_(Isolate::Current()) {
+  }
+  ~ReusableHandleScope() {
+    ResetHandles();
+  }
+
+#define REUSABLE_HANDLE_ACCESSORS(object)                                      \
+  object& object##Handle() {                                                   \
+    ASSERT(isolate_->object##_handle_ != NULL);                                \
+    return *isolate_->object##_handle_;                                        \
+  }                                                                            \
+
+  REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_ACCESSORS)
+#undef REUSABLE_HANDLE_ACCESSORS
+
+ private:
+  void ResetHandles();
+  Isolate* isolate_;
+  DISALLOW_COPY_AND_ASSIGN(ReusableHandleScope);
+};
+#endif  // defined(DEBUG)
+
+
+
 // When we need to execute code in an isolate, we use the
 // StartIsolateScope.
 class StartIsolateScope {
diff --git a/runtime/vm/mirrors_api_impl.cc b/runtime/vm/mirrors_api_impl.cc
index c79d3ce..537c9ed 100644
--- a/runtime/vm/mirrors_api_impl.cc
+++ b/runtime/vm/mirrors_api_impl.cc
@@ -238,7 +238,8 @@
         if (func.kind() == RawFunction::kImplicitGetter ||
             func.kind() == RawFunction::kImplicitSetter ||
             func.kind() == RawFunction::kConstImplicitGetter ||
-            func.kind() == RawFunction::kMethodExtractor) {
+            func.kind() == RawFunction::kMethodExtractor ||
+            func.kind() == RawFunction::kNoSuchMethodDispatcher) {
           continue;
         }
 
diff --git a/runtime/vm/native_entry_test.cc b/runtime/vm/native_entry_test.cc
index 217c080..c8276f1 100644
--- a/runtime/vm/native_entry_test.cc
+++ b/runtime/vm/native_entry_test.cc
@@ -87,25 +87,4 @@
   Dart_ExitScope();
 }
 
-
-// Test code patching.
-void TestStaticCallPatching(Dart_NativeArguments args) {
-  Dart_EnterScope();
-  DartFrameIterator iterator;
-  iterator.NextFrame();  // Skip native call.
-  StackFrame* static_caller_frame = iterator.NextFrame();
-  const Code& code = Code::Handle(static_caller_frame->LookupDartCode());
-  uword target_address =
-      CodePatcher::GetStaticCallTargetAt(static_caller_frame->pc(), code);
-  const Function& target_function =
-      Function::Handle(code.GetStaticCallTargetFunctionAt(
-          static_caller_frame->pc()));
-  EXPECT(String::Handle(target_function.name()).
-      Equals(String::Handle(String::New("NativePatchStaticCall"))));
-  const uword function_entry_address =
-      Code::Handle(target_function.CurrentCode()).EntryPoint();
-  EXPECT_EQ(function_entry_address, target_address);
-  Dart_ExitScope();
-}
-
 }  // namespace dart
diff --git a/runtime/vm/native_entry_test.h b/runtime/vm/native_entry_test.h
index 0d4923a..2c34548 100644
--- a/runtime/vm/native_entry_test.h
+++ b/runtime/vm/native_entry_test.h
@@ -12,7 +12,6 @@
 void TestSmiSub(Dart_NativeArguments args);
 void TestSmiSum(Dart_NativeArguments args);
 void TestNonNullSmiSum(Dart_NativeArguments args);
-void TestStaticCallPatching(Dart_NativeArguments args);
 
 }  // namespace dart
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index c0e5a65..966aa45 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1614,25 +1614,34 @@
   // To work properly, this call requires the super class of this class to be
   // resolved, which is checked by the SuperClass() call.
   Isolate* isolate = Isolate::Current();
-  Class& cls = Class::Handle(isolate, raw());
+  ReusableHandleScope reused_handles(isolate);
+  Class& cls = reused_handles.ClassHandle();
+  TypeArguments& type_params = reused_handles.TypeArgumentsHandle();
+  AbstractType& sup_type = reused_handles.AbstractTypeHandle();
+  cls ^= raw();
   intptr_t num_type_args = 0;
 
   do {
     if (cls.IsSignatureClass()) {
-      const Function& signature_fun =
-          Function::Handle(isolate, cls.signature_function());
+      Function& signature_fun = reused_handles.FunctionHandle();
+      signature_fun ^= cls.signature_function();
       if (!signature_fun.is_static() &&
           !signature_fun.HasInstantiatedSignature()) {
         cls = signature_fun.Owner();
       }
     }
-    num_type_args += cls.NumTypeParameters();
+    if (cls.type_parameters() != TypeArguments::null()) {
+      type_params ^= cls.type_parameters();
+      num_type_args += type_params.Length();
+    }
+
     // Super type of Object class is null.
     if (cls.super_type() == AbstractType::null() ||
         cls.super_type() == isolate->object_store()->object_type()) {
       break;
     }
-    cls = cls.SuperClass();
+    sup_type ^= cls.super_type();
+    cls = sup_type.type_class();
   } while (true);
   return num_type_args;
 }
@@ -1653,7 +1662,10 @@
   if (super_type() == AbstractType::null()) {
     return Class::null();
   }
-  const AbstractType& sup_type = AbstractType::Handle(super_type());
+  Isolate* isolate = Isolate::Current();
+  ReusableHandleScope reused_handles(isolate);
+  AbstractType& sup_type = reused_handles.AbstractTypeHandle();
+  sup_type ^= super_type();
   return sup_type.type_class();
 }
 
@@ -1672,11 +1684,14 @@
 RawTypeParameter* Class::LookupTypeParameter(const String& type_name,
                                              intptr_t token_pos) const {
   ASSERT(!type_name.IsNull());
-  const TypeArguments& type_params = TypeArguments::Handle(type_parameters());
+  Isolate* isolate = Isolate::Current();
+  ReusableHandleScope reused_handles(isolate);
+  TypeArguments& type_params = reused_handles.TypeArgumentsHandle();
+  type_params ^= type_parameters();
+  TypeParameter& type_param = reused_handles.TypeParameterHandle();
+  String& type_param_name = reused_handles.StringHandle();
   if (!type_params.IsNull()) {
     intptr_t num_type_params = type_params.Length();
-    TypeParameter& type_param = TypeParameter::Handle();
-    String& type_param_name = String::Handle();
     for (intptr_t i = 0; i < num_type_params; i++) {
       type_param ^= type_params.TypeAt(i);
       type_param_name = type_param.name();
@@ -2449,12 +2464,14 @@
   if (EnsureIsFinalized(isolate) != Error::null()) {
     return Function::null();
   }
-  Array& funcs = Array::Handle(isolate, functions());
+  ReusableHandleScope reused_handles(isolate);
+  Array& funcs = reused_handles.ArrayHandle();
+  funcs ^= functions();
   if (funcs.IsNull()) {
     // This can occur, e.g., for Null classes.
     return Function::null();
   }
-  Function& function = Function::Handle(isolate);
+  Function& function = reused_handles.FunctionHandle();
   const intptr_t len = funcs.Length();
   if (name.IsSymbol()) {
     // Quick Symbol compare.
@@ -2466,7 +2483,7 @@
       }
     }
   } else {
-    String& function_name = String::Handle(isolate);
+    String& function_name = reused_handles.StringHandle();
     for (intptr_t i = 0; i < len; i++) {
       function ^= funcs.At(i);
       function_name ^= function.name();
@@ -2486,13 +2503,15 @@
   if (EnsureIsFinalized(isolate) != Error::null()) {
     return Function::null();
   }
-  Array& funcs = Array::Handle(isolate, functions());
+  ReusableHandleScope reused_handles(isolate);
+  Array& funcs = reused_handles.ArrayHandle();
+  funcs ^= functions();
   if (funcs.IsNull()) {
     // This can occur, e.g., for Null classes.
     return Function::null();
   }
-  Function& function = Function::Handle(isolate);
-  String& function_name = String::Handle(isolate);
+  Function& function = reused_handles.FunctionHandle();
+  String& function_name = reused_handles.StringHandle();
   intptr_t len = funcs.Length();
   for (intptr_t i = 0; i < len; i++) {
     function ^= funcs.At(i);
@@ -2523,9 +2542,11 @@
   if (EnsureIsFinalized(isolate) != Error::null()) {
     return Function::null();
   }
-  Array& funcs = Array::Handle(isolate, functions());
-  Function& function = Function::Handle(isolate, Function::null());
-  String& function_name = String::Handle(isolate, String::null());
+  ReusableHandleScope reused_handles(isolate);
+  Array& funcs = reused_handles.ArrayHandle();
+  funcs ^= functions();
+  Function& function = reused_handles.FunctionHandle();
+  String& function_name = reused_handles.StringHandle();
   intptr_t len = funcs.Length();
   for (intptr_t i = 0; i < len; i++) {
     function ^= funcs.At(i);
@@ -2586,9 +2607,11 @@
   if (EnsureIsFinalized(isolate) != Error::null()) {
     return Field::null();
   }
-  const Array& flds = Array::Handle(isolate, fields());
-  Field& field = Field::Handle(isolate, Field::null());
-  String& field_name = String::Handle(isolate, String::null());
+  ReusableHandleScope reused_handles(isolate);
+  Array& flds = reused_handles.ArrayHandle();
+  flds ^= fields();
+  Field& field = reused_handles.FieldHandle();
+  String& field_name = reused_handles.StringHandle();
   intptr_t len = flds.Length();
   for (intptr_t i = 0; i < len; i++) {
     field ^= flds.At(i);
@@ -4701,6 +4724,9 @@
     case RawFunction::kMethodExtractor:
       kind_str = " method-extractor";
       break;
+    case RawFunction::kNoSuchMethodDispatcher:
+      kind_str = " no-such-method-dispatcher";
+      break;
     default:
       UNREACHABLE();
   }
@@ -5363,8 +5389,7 @@
       token_obj_(Object::Handle()),
       literal_token_(LiteralToken::Handle()),
       literal_str_(String::Handle()) {
-    const String& empty_literal = String::Handle();
-    token_objects_.Add(empty_literal);
+    token_objects_.Add(Object::null_string());
   }
   ~CompressedTokenStreamData() {
   }
@@ -6195,12 +6220,14 @@
 
 RawObject* Library::LookupEntry(const String& name, intptr_t *index) const {
   Isolate* isolate = Isolate::Current();
-  const Array& dict = Array::Handle(isolate, dictionary());
+  ReusableHandleScope reused_handles(isolate);
+  Array& dict = reused_handles.ArrayHandle();
+  dict ^= dictionary();
   intptr_t dict_size = dict.Length() - 1;
   *index = name.Hash() % dict_size;
 
-  Object& entry = Object::Handle(isolate);
-  String& entry_name = String::Handle(isolate);
+  Object& entry = reused_handles.ObjectHandle();
+  String& entry_name = reused_handles.StringHandle();
   entry = dict.At(*index);
   // Search the entry in the hash set.
   while (!entry.IsNull()) {
@@ -7284,17 +7311,18 @@
 
 const char* PcDescriptors::KindAsStr(intptr_t index) const {
   switch (DescriptorKind(index)) {
-    case PcDescriptors::kDeopt:         return "deopt        ";
-    case PcDescriptors::kEntryPatch:    return "entry-patch  ";
-    case PcDescriptors::kPatchCode:     return "patch        ";
-    case PcDescriptors::kLazyDeoptJump: return "lazy-deopt   ";
-    case PcDescriptors::kIcCall:        return "ic-call      ";
-    case PcDescriptors::kFuncCall:      return "fn-call      ";
-    case PcDescriptors::kClosureCall:   return "closure-call ";
-    case PcDescriptors::kReturn:        return "return       ";
-    case PcDescriptors::kRuntimeCall:   return "runtime-call ";
-    case PcDescriptors::kOsrEntry:      return "osr-entry    ";
-    case PcDescriptors::kOther:         return "other        ";
+    case PcDescriptors::kDeopt:           return "deopt        ";
+    case PcDescriptors::kEntryPatch:      return "entry-patch  ";
+    case PcDescriptors::kPatchCode:       return "patch        ";
+    case PcDescriptors::kLazyDeoptJump:   return "lazy-deopt   ";
+    case PcDescriptors::kIcCall:          return "ic-call      ";
+    case PcDescriptors::kOptStaticCall:   return "opt-call     ";
+    case PcDescriptors::kUnoptStaticCall: return "unopt-call   ";
+    case PcDescriptors::kClosureCall:     return "closure-call ";
+    case PcDescriptors::kReturn:          return "return       ";
+    case PcDescriptors::kRuntimeCall:     return "runtime-call ";
+    case PcDescriptors::kOsrEntry:        return "osr-entry    ";
+    case PcDescriptors::kOther:           return "other        ";
   }
   UNREACHABLE();
   return "";
@@ -8215,14 +8243,20 @@
   ICData& ic_data_obj = ICData::Handle();
   intptr_t max_id = -1;
   for (intptr_t i = 0; i < descriptors.Length(); i++) {
-    if (descriptors.DescriptorKind(i) == PcDescriptors::kIcCall) {
+    PcDescriptors::Kind kind = descriptors.DescriptorKind(i);
+    if ((kind == PcDescriptors::kIcCall) ||
+        (kind == PcDescriptors::kUnoptStaticCall)) {
       intptr_t deopt_id = descriptors.DeoptId(i);
       if (deopt_id > max_id) {
         max_id = deopt_id;
       }
       node_ids->Add(deopt_id);
-      CodePatcher::GetInstanceCallAt(descriptors.PC(i), *this,
-                                     &ic_data_obj, NULL);
+      uword ret_addr = descriptors.PC(i);
+      if (kind == PcDescriptors::kIcCall) {
+        CodePatcher::GetInstanceCallAt(ret_addr, *this, &ic_data_obj);
+      } else {
+        CodePatcher::GetUnoptimizedStaticCallAt(ret_addr, *this, &ic_data_obj);
+      }
       ic_data_objs.Add(ic_data_obj);
     }
   }
@@ -8247,26 +8281,6 @@
 }
 
 
-void Code::ExtractUncalledStaticCallDeoptIds(
-    GrowableArray<intptr_t>* deopt_ids) const {
-  ASSERT(!IsNull() && !is_optimized());
-  ASSERT(deopt_ids != NULL);
-  deopt_ids->Clear();
-  const PcDescriptors& descriptors =
-      PcDescriptors::Handle(this->pc_descriptors());
-  for (intptr_t i = 0; i < descriptors.Length(); i++) {
-    if (descriptors.DescriptorKind(i) == PcDescriptors::kFuncCall) {
-      // Static call.
-      const uword target_addr =
-          CodePatcher::GetStaticCallTargetAt(descriptors.PC(i), *this);
-      if (target_addr == StubCode::CallStaticFunctionEntryPoint()) {
-        deopt_ids->Add(descriptors.DeoptId(i));
-      }
-    }
-  }
-}
-
-
 RawStackmap* Code::GetStackmap(uword pc, Array* maps, Stackmap* map) const {
   // This code is used during iterating frames during a GC and hence it
   // should not in turn start a GC.
@@ -8456,6 +8470,10 @@
 }
 
 
+void ICData::set_arguments_descriptor(const Array& value) const {
+  StorePointer(&raw_ptr()->args_descriptor_, value.raw());
+}
+
 void ICData::set_deopt_id(intptr_t value) const {
   raw_ptr()->deopt_id_ = value;
 }
@@ -8527,6 +8545,25 @@
 #endif  // DEBUG
 
 
+// Used for unoptimized static calls when no class-ids are checked.
+void ICData::AddTarget(const Function& target) const {
+  ASSERT(num_args_tested() == 0);
+  // Can add only once.
+  const intptr_t old_num = NumberOfChecks();
+  ASSERT(old_num == 0);
+  Array& data = Array::Handle(ic_data());
+  const intptr_t new_len = data.Length() + TestEntryLength();
+  data = Array::Grow(data, new_len, Heap::kOld);
+  set_ic_data(data);
+  WriteSentinel(data);
+  intptr_t data_pos = old_num * TestEntryLength();
+  ASSERT(!target.IsNull());
+  data.SetAt(data_pos++, target);
+  const Smi& value = Smi::Handle(Smi::New(0));
+  data.SetAt(data_pos, value);
+}
+
+
 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
                       const Function& target) const {
   DEBUG_ASSERT(!HasCheck(class_ids));
@@ -8666,6 +8703,7 @@
 
 
 intptr_t ICData::AggregateCount() const {
+  if (IsNull()) return 0;
   const intptr_t len = NumberOfChecks();
   intptr_t count = 0;
   for (intptr_t i = 0; i < len; i++) {
@@ -8697,6 +8735,7 @@
   ICData& result = ICData::Handle(ICData::New(
       Function::Handle(function()),
       String::Handle(target_name()),
+      Array::Handle(arguments_descriptor()),
       deopt_id(),
       kNumArgsTested));
   const intptr_t len = NumberOfChecks();
@@ -8792,10 +8831,11 @@
 
 RawICData* ICData::New(const Function& function,
                        const String& target_name,
+                       const Array& arguments_descriptor,
                        intptr_t deopt_id,
                        intptr_t num_args_tested) {
   ASSERT(Object::icdata_class() != Class::null());
-  ASSERT(num_args_tested > 0);
+  ASSERT(num_args_tested >= 0);
   ICData& result = ICData::Handle();
   {
     // IC data objects are long living objects, allocate them in old generation.
@@ -8807,6 +8847,7 @@
   }
   result.set_function(function);
   result.set_target_name(target_name);
+  result.set_arguments_descriptor(arguments_descriptor);
   result.set_deopt_id(deopt_id);
   result.set_num_args_tested(num_args_tested);
   result.set_deopt_reason(kDeoptUnknown);
@@ -10630,7 +10671,8 @@
 // Throw FiftyThreeBitOverflow exception.
 static void ThrowFiftyThreeBitOverflow(const Integer& i) {
   const Array& exc_args = Array::Handle(Array::New(1));
-  exc_args.SetAt(0, i);
+  const String& i_str = String::Handle(String::New(i.ToCString()));
+  exc_args.SetAt(0, i_str);
   Exceptions::ThrowByType(Exceptions::kFiftyThreeBitOverflowError, exc_args);
 }
 
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 1f847b3..b307f6a 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -32,6 +32,7 @@
 class DeoptInstr;
 class FinalizablePersistentHandle;
 class LocalScope;
+class ReusableHandleScope;
 class Symbols;
 
 #if defined(DEBUG)
@@ -169,6 +170,7 @@
     return raw()->ptr();                                                       \
   }                                                                            \
   SNAPSHOT_READER_SUPPORT(object)                                              \
+  friend class Isolate;                                                        \
   friend class StackFrame;                                                     \
 
 // This macro is used to denote types that do not have a sub-type.
@@ -190,6 +192,7 @@
     return raw()->ptr();                                                       \
   }                                                                            \
   SNAPSHOT_READER_SUPPORT(object)                                              \
+  friend class Isolate;                                                        \
   friend class StackFrame;                                                     \
 
 class Object {
@@ -591,6 +594,8 @@
   friend class TwoByteString;
   friend class ExternalOneByteString;
   friend class ExternalTwoByteString;
+  friend class Isolate;
+  friend class ReusableHandleScope;
 
   DISALLOW_ALLOCATION();
   DISALLOW_COPY_AND_ASSIGN(Object);
@@ -1395,6 +1400,10 @@
     return kind() == RawFunction::kMethodExtractor;
   }
 
+  bool IsNoSuchMethodDispatcher() const {
+    return kind() == RawFunction::kNoSuchMethodDispatcher;
+  }
+
   // Returns true iff an implicit closure function has been created
   // for this function.
   bool HasImplicitClosureFunction() const {
@@ -1439,6 +1448,7 @@
       case RawFunction::kImplicitGetter:
       case RawFunction::kImplicitSetter:
       case RawFunction::kMethodExtractor:
+      case RawFunction::kNoSuchMethodDispatcher:
         return true;
       case RawFunction::kClosureFunction:
       case RawFunction::kConstructor:
@@ -2354,7 +2364,6 @@
   friend class Class;
   friend class Debugger;
   friend class DictionaryIterator;
-  friend class Isolate;
   friend class Namespace;
   friend class Object;
 };
@@ -2390,7 +2399,6 @@
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(LibraryPrefix, Object);
   friend class Class;
-  friend class Isolate;
 };
 
 
@@ -2538,7 +2546,8 @@
     kPatchCode,        // Buffer for patching code entry.
     kLazyDeoptJump,    // Lazy deoptimization trampoline.
     kIcCall,           // IC call.
-    kFuncCall,         // Call to known target, e.g. static call.
+    kOptStaticCall,    // Call directly to known target, e.g. static call.
+    kUnoptStaticCall,  // Call to a known target via a stub.
     kClosureCall,      // Closure call.
     kRuntimeCall,      // Runtime call.
     kReturn,           // Return from function.
@@ -2982,11 +2991,6 @@
   // Returns an array indexed by deopt id, containing the extracted ICData.
   RawArray* ExtractTypeFeedbackArray() const;
 
-  // Returns deopt-ids of all static calls that were never resolved, i.e.,
-  // never executed.
-  void ExtractUncalledStaticCallDeoptIds(
-      GrowableArray<intptr_t>* deopt_ids) const;
-
  private:
   // An object finder visitor interface.
   class FindRawCodeVisitor : public FindObjectVisitor {
@@ -3183,6 +3187,10 @@
     return raw_ptr()->target_name_;
   }
 
+  RawArray* arguments_descriptor() const {
+    return raw_ptr()->args_descriptor_;
+  }
+
   intptr_t num_args_tested() const {
     return raw_ptr()->num_args_tested_;
   }
@@ -3217,6 +3225,10 @@
     return OFFSET_OF(RawICData, num_args_tested_);
   }
 
+  static intptr_t arguments_descriptor_offset() {
+    return OFFSET_OF(RawICData, args_descriptor_);
+  }
+
   static intptr_t ic_data_offset() {
     return OFFSET_OF(RawICData, ic_data_);
   }
@@ -3229,6 +3241,9 @@
     return OFFSET_OF(RawICData, is_closure_call_);
   }
 
+  // Used for unoptimized static calls when no class-ids are checked.
+  void AddTarget(const Function& target) const;
+
   // Adding checks.
 
   // Adds one more class test to ICData. Length of 'classes' must be equal to
@@ -3274,6 +3289,7 @@
 
   static RawICData* New(const Function& caller_function,
                         const String& target_name,
+                        const Array& arguments_descriptor,
                         intptr_t deopt_id,
                         intptr_t num_args_tested);
 
@@ -3294,6 +3310,7 @@
 
   void set_function(const Function& value) const;
   void set_target_name(const String& value) const;
+  void set_arguments_descriptor(const Array& value) const;
   void set_deopt_id(intptr_t value) const;
   void set_num_args_tested(intptr_t value) const;
   void set_ic_data(const Array& value) const;
@@ -5812,18 +5829,18 @@
 }
 
 
-void Object::SetRaw(RawObject* value) {
+DART_FORCE_INLINE void Object::SetRaw(RawObject* value) {
   // NOTE: The assignment "raw_ = value" should be the first statement in
   // this function. Also do not use 'value' in this function after the
   // assignment (use 'raw_' instead).
   raw_ = value;
-  if ((reinterpret_cast<uword>(raw_) & kSmiTagMask) == kSmiTag) {
+  if ((reinterpret_cast<uword>(value) & kSmiTagMask) == kSmiTag) {
     set_vtable(Smi::handle_vtable_);
     return;
   }
-  intptr_t cid = raw_->GetClassId();
+  intptr_t cid = value->GetClassId();
   if (cid >= kNumPredefinedCids) {
-      cid = kInstanceCid;
+    cid = kInstanceCid;
   }
   set_vtable(builtin_vtables_[cid]);
 #if defined(DEBUG)
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index f235827..d545860 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -7,6 +7,7 @@
 #include "vm/bigint_operations.h"
 #include "vm/class_finalizer.h"
 #include "vm/dart_api_impl.h"
+#include "vm/dart_entry.h"
 #include "vm/isolate.h"
 #include "vm/object.h"
 #include "vm/object_store.h"
@@ -2495,13 +2496,16 @@
   const intptr_t id = 12;
   const intptr_t num_args_tested = 1;
   const String& target_name = String::Handle(String::New("Thun"));
+  const Array& args_descriptor =
+      Array::Handle(ArgumentsDescriptor::New(1, Object::null_array()));
   ICData& o1 = ICData::Handle();
-  o1 = ICData::New(function, target_name, id, num_args_tested);
+  o1 = ICData::New(function, target_name, args_descriptor, id, num_args_tested);
   EXPECT_EQ(1, o1.num_args_tested());
   EXPECT_EQ(id, o1.deopt_id());
   EXPECT_EQ(function.raw(), o1.function());
   EXPECT_EQ(0, o1.NumberOfChecks());
   EXPECT_EQ(target_name.raw(), o1.target_name());
+  EXPECT_EQ(args_descriptor.raw(), o1.arguments_descriptor());
 
   const Function& target1 = Function::Handle(GetDummyTarget("Thun"));
   o1.AddReceiverCheck(kSmiCid, target1);
@@ -2525,7 +2529,7 @@
   EXPECT_EQ(target2.raw(), test_target.raw());
 
   ICData& o2 = ICData::Handle();
-  o2 = ICData::New(function, target_name, 57, 2);
+  o2 = ICData::New(function, target_name, args_descriptor, 57, 2);
   EXPECT_EQ(2, o2.num_args_tested());
   EXPECT_EQ(57, o2.deopt_id());
   EXPECT_EQ(function.raw(), o2.function());
@@ -2540,6 +2544,13 @@
   EXPECT_EQ(kSmiCid, test_class_ids[0]);
   EXPECT_EQ(kSmiCid, test_class_ids[1]);
   EXPECT_EQ(target1.raw(), test_target.raw());
+
+  // Check ICData for unoptimized static calls.
+  const intptr_t kNumArgsChecked = 0;
+  const ICData& scall_icdata = ICData::Handle(
+      ICData::New(function, target_name, args_descriptor, 57, kNumArgsChecked));
+  scall_icdata.AddTarget(target1);
+  EXPECT_EQ(target1.raw(), scall_icdata.GetTargetAt(0));
 }
 
 
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 0aec272..8773376 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -802,6 +802,9 @@
     case RawFunction::kMethodExtractor:
       node_sequence = parser.ParseMethodExtractor(func);
       break;
+    case RawFunction::kNoSuchMethodDispatcher:
+      node_sequence = parser.ParseNoSuchMethodDispatcher(func);
+      break;
     default:
       UNREACHABLE();
   }
@@ -920,6 +923,21 @@
   const Field& field =
       Field::ZoneHandle(field_class.LookupStaticField(field_name));
 
+  if (!field.is_const() &&
+      (field.value() != Object::transition_sentinel().raw()) &&
+      (field.value() != Object::sentinel().raw())) {
+    // The field has already been initialized at compile time (this can
+    // happen, e.g., if we are recompiling for optimization).  There is no
+    // need to check for initialization and compile the potentially very
+    // large initialization code.  By skipping this code, the deoptimization
+    // ids will not line up with the original code, but this is safe because
+    // LoadStaticField does not deoptimize.
+    LoadStaticFieldNode* load_node = new LoadStaticFieldNode(ident_pos, field);
+    ReturnNode* return_node = new ReturnNode(ident_pos, load_node);
+    current_block_->statements->Add(return_node);
+    return CloseBlock();
+  }
+
   // Static const fields must have an initializer.
   ExpectToken(Token::kASSIGN);
 
@@ -1119,6 +1137,46 @@
 }
 
 
+SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) {
+  TRACE_PARSER("ParseNoSuchMethodDispatcher");
+  ParamList params;
+
+  ASSERT(func.IsNoSuchMethodDispatcher());
+  intptr_t token_pos = func.token_pos();
+  ASSERT(func.token_pos() == 0);
+  ASSERT(current_class().raw() == func.Owner());
+  params.AddReceiver(ReceiverType(token_pos));
+  ASSERT(func.num_fixed_parameters() == 1);  // Receiver.
+  ASSERT(!func.HasOptionalParameters());
+
+  // Build local scope for function and populate with the formal parameters.
+  OpenFunctionBlock(func);
+  LocalScope* scope = current_block_->scope;
+  AddFormalParamsToScope(&params, scope);
+
+  // Receiver is local 0.
+  LocalVariable* receiver = scope->VariableAt(0);
+  LoadLocalNode* load_receiver = new LoadLocalNode(token_pos, receiver);
+
+  ArgumentListNode* func_args = new ArgumentListNode(token_pos);
+  func_args->Add(load_receiver);
+  const String& func_name = String::ZoneHandle(func.name());
+  ArgumentListNode* arguments = BuildNoSuchMethodArguments(token_pos,
+                                                           func_name,
+                                                           *func_args);
+  const Function& no_such_method = Function::ZoneHandle(
+        Resolver::ResolveDynamicAnyArgs(Class::Handle(func.Owner()),
+                                        Symbols::NoSuchMethod()));
+  StaticCallNode* call =
+      new StaticCallNode(token_pos, no_such_method, arguments);
+
+
+  ReturnNode* return_node = new ReturnNode(token_pos, call);
+  current_block_->statements->Add(return_node);
+  return CloseBlock();
+}
+
+
 void Parser::SkipBlock() {
   ASSERT(CurrentToken() == Token::kLBRACE);
   GrowableArray<Token::Kind> token_stack(8);
@@ -4363,9 +4421,13 @@
     }
     ErrorMsg(token_pos, "no library handler registered");
   }
+  // Block class finalization attempts when calling into the library
+  // tag handler.
+  isolate()->BlockClassFinalization();
   Dart_Handle result = handler(tag,
                                Api::NewHandle(isolate(), library_.raw()),
                                Api::NewHandle(isolate(), url.raw()));
+  isolate()->UnblockClassFinalization();
   if (Dart_IsError(result)) {
     // In case of an error we append an explanatory error message to the
     // error obtained from the library tag handler.
@@ -8272,13 +8334,13 @@
     ASSERT(arg->IsLiteralNode());
     arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal());
   }
-  const Array& arg_descriptor =
+  const Array& args_descriptor =
       Array::Handle(ArgumentsDescriptor::New(num_arguments,
                                              arguments->names()));
   const Object& result =
       Object::Handle(DartEntry::InvokeFunction(constructor,
                                                arg_values,
-                                               arg_descriptor));
+                                               args_descriptor));
   if (result.IsError()) {
       // An exception may not occur in every parse attempt, i.e., the
       // generated AST is not deterministic. Therefore mark the function as
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 00681dc..f80c674 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -63,7 +63,8 @@
     return default_parameter_values_;
   }
   void set_default_parameter_values(const Array& default_parameter_values) {
-    ASSERT(default_parameter_values.IsZoneHandle());
+    ASSERT(default_parameter_values.IsZoneHandle() ||
+           default_parameter_values.InVMHeap());
     default_parameter_values_ = default_parameter_values.raw();
   }
 
@@ -438,6 +439,7 @@
   SequenceNode* ParseInstanceSetter(const Function& func);
   SequenceNode* ParseStaticConstGetter(const Function& func);
   SequenceNode* ParseMethodExtractor(const Function& func);
+  SequenceNode* ParseNoSuchMethodDispatcher(const Function& func);
 
   void ChainNewBlock(LocalScope* outer_scope);
   void OpenBlock();
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 9794c11..7fedccb 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -597,6 +597,7 @@
     kImplicitSetter,     // represents an implicit setter for fields.
     kConstImplicitGetter,  // represents an implicit const getter for fields.
     kMethodExtractor,  // converts method into implicit closure on the receiver.
+    kNoSuchMethodDispatcher,  // invokes noSuchMethod.
   };
 
  private:
@@ -1022,16 +1023,17 @@
   RawObject** from() {
     return reinterpret_cast<RawObject**>(&ptr()->function_);
   }
-  RawFunction* function_;     // Parent/calling function of this IC.
-  RawString* target_name_;    // Name of target function.
-  RawArray* ic_data_;         // Contains test class-ids and target functions.
+  RawFunction* function_;      // Parent/calling function of this IC.
+  RawString* target_name_;     // Name of target function.
+  RawArray* args_descriptor_;  // Arguments descriptor.
+  RawArray* ic_data_;          // Contains class-ids, target and count.
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->ic_data_);
   }
-  intptr_t deopt_id_;         // Deoptimization id corresponding to this IC.
-  intptr_t num_args_tested_;  // Number of arguments tested in IC.
-  uint8_t deopt_reason_;      // Last deoptimization reason.
-  uint8_t is_closure_call_;   // 0 or 1.
+  intptr_t deopt_id_;          // Deoptimization id corresponding to this IC.
+  intptr_t num_args_tested_;   // Number of arguments tested in IC.
+  uint8_t deopt_reason_;       // Last deoptimization reason.
+  uint8_t is_closure_call_;    // 0 or 1.
 };
 
 
diff --git a/runtime/vm/resolver.cc b/runtime/vm/resolver.cc
index 5a55b48..78bf848 100644
--- a/runtime/vm/resolver.cc
+++ b/runtime/vm/resolver.cc
@@ -138,7 +138,7 @@
     // Getter invocation might actually be a method extraction.
     if (is_getter && function.IsNull()) {
       function ^= cls.LookupDynamicFunction(field_name);
-      if (!function.IsNull()) {
+      if (!function.IsNull() && !function.IsNoSuchMethodDispatcher()) {
         // We were looking for the getter but found a method with the same name.
         // Create a method extractor and return it.
         function ^= CreateMethodExtractor(function_name, function);
diff --git a/runtime/vm/scanner.cc b/runtime/vm/scanner.cc
index 896142c..fff829a 100644
--- a/runtime/vm/scanner.cc
+++ b/runtime/vm/scanner.cc
@@ -15,7 +15,6 @@
 
 namespace dart {
 
-DEFINE_FLAG(bool, disable_privacy, false, "Disable library privacy.");
 DEFINE_FLAG(bool, print_tokens, false, "Print scanned tokens.");
 
 void Scanner::InitKeywordTable() {
@@ -328,7 +327,7 @@
   current_token_.kind = Token::kIDENT;
   String& literal =
       String::ZoneHandle(Symbols::New(source_, ident_pos, ident_length));
-  if ((ident_char0 == kPrivateIdentifierStart) && !FLAG_disable_privacy) {
+  if (ident_char0 == kPrivateIdentifierStart) {
     // Private identifiers are mangled on a per script basis.
     literal = String::Concat(literal, private_key_);
     literal = Symbols::New(literal);
@@ -392,19 +391,6 @@
 }
 
 
-RawString* Scanner::ConsumeIdentChars(bool allow_dollar) {
-  ASSERT(IsIdentStartChar(c0_));
-  ASSERT(allow_dollar || (c0_ != '$'));
-  int ident_length = 0;
-  int32_t ident_pos = lookahead_pos_;
-  while (IsIdentChar(c0_) && (allow_dollar || (c0_ != '$'))) {
-    ReadChar();
-    ident_length++;
-  }
-  return Symbols::New(source_, ident_pos, ident_length);
-}
-
-
 void Scanner::SkipLine() {
   while (c0_ != '\n' && c0_ != '\0') {
     ReadChar();
diff --git a/runtime/vm/scanner.h b/runtime/vm/scanner.h
index 42dc417..316ac98 100644
--- a/runtime/vm/scanner.h
+++ b/runtime/vm/scanner.h
@@ -187,7 +187,6 @@
   void ScanEscapedCodePoint(int32_t* escaped_char);
 
   // Reads identifier.
-  RawString* ConsumeIdentChars(bool allow_dollar);
   void ScanIdentChars(bool allow_dollar);
   void ScanIdent() {
     ScanIdentChars(true);
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index acfed60..cc08b23 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -2968,15 +2968,24 @@
                         int32_t parameter0,
                         int32_t parameter1,
                         int32_t parameter2,
-                        int32_t parameter3) {
+                        int32_t parameter3,
+                        bool fp_return,
+                        bool fp_args) {
   // Save the SP register before the call so we can restore it.
   int32_t sp_before_call = get_register(SP);
 
   // Setup parameters.
-  set_register(R0, parameter0);
-  set_register(R1, parameter1);
-  set_register(R2, parameter2);
-  set_register(R3, parameter3);
+  if (fp_args) {
+    set_sregister(S0, bit_cast<float, int32_t>(parameter0));
+    set_sregister(S1, bit_cast<float, int32_t>(parameter1));
+    set_sregister(S2, bit_cast<float, int32_t>(parameter2));
+    set_sregister(S3, bit_cast<float, int32_t>(parameter3));
+  } else {
+    set_register(R0, parameter0);
+    set_register(R1, parameter1);
+    set_register(R2, parameter2);
+    set_register(R3, parameter3);
+  }
 
   // Make sure the activation frames are properly aligned.
   int32_t stack_pointer = sp_before_call;
@@ -3042,7 +3051,13 @@
 
   // Restore the SP register and return R1:R0.
   set_register(SP, sp_before_call);
-  return Utils::LowHighTo64Bits(get_register(R0), get_register(R1));
+  int64_t return_value;
+  if (fp_return) {
+    return_value = bit_cast<int64_t, double>(get_dregister(D0));
+  } else {
+    return_value = Utils::LowHighTo64Bits(get_register(R0), get_register(R1));
+  }
+  return return_value;
 }
 
 
@@ -3073,11 +3088,10 @@
   set_register(PC, static_cast<int32_t>(pc));
   set_register(SP, static_cast<int32_t>(sp));
   set_register(FP, static_cast<int32_t>(fp));
-  ASSERT(raw_exception != NULL);
+
+  ASSERT(raw_exception != Object::null());
   set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
-  if (raw_stacktrace != NULL) {
-    set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
-  }
+  set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
   buf->Longjmp();
 }
 
diff --git a/runtime/vm/simulator_arm.h b/runtime/vm/simulator_arm.h
index d6e8409..5ccfc09 100644
--- a/runtime/vm/simulator_arm.h
+++ b/runtime/vm/simulator_arm.h
@@ -65,12 +65,17 @@
 
   // Dart generally calls into generated code with 5 parameters. This is a
   // convenience function, which sets up the simulator state and grabs the
-  // result on return.
+  // result on return. When fp_return is true the return value is the D0
+  // floating point register. Otherwise, the return value is R1:R0.
+  // If fp_args is true, the parameters0-3 are placed in S0-3. Otherwise, they
+  // are placed in R0-3.
   int64_t Call(int32_t entry,
                int32_t parameter0,
                int32_t parameter1,
                int32_t parameter2,
-               int32_t parameter3);
+               int32_t parameter3,
+               bool fp_return = false,
+               bool fp_args = false);
 
   // Implementation of atomic compare and exchange in the same synchronization
   // domain as other synchronization primitive instructions (e.g. ldrex, strex).
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index 0a12de3..a04d8f1 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -727,6 +727,23 @@
 }
 
 
+void Simulator::set_dregister_bits(DRegister reg, int64_t value) {
+  ASSERT(reg >= 0);
+  ASSERT(reg < kNumberOfDRegisters);
+  FRegister lo = static_cast<FRegister>(reg * 2);
+  FRegister hi = static_cast<FRegister>((reg * 2) + 1);
+  set_fregister(lo, Utils::Low32Bits(value));
+  set_fregister(hi, Utils::High32Bits(value));
+}
+
+
+void Simulator::set_dregister(DRegister reg, double value) {
+  ASSERT(reg >= 0);
+  ASSERT(reg < kNumberOfDRegisters);
+  set_dregister_bits(reg, bit_cast<int64_t, double>(value));
+}
+
+
 // Get the register from the architecture state.
 int32_t Simulator::get_register(Register reg) const {
   if (reg == R0) {
@@ -769,6 +786,23 @@
 }
 
 
+int64_t Simulator::get_dregister_bits(DRegister reg) const {
+  ASSERT(reg >= 0);
+  ASSERT(reg < kNumberOfDRegisters);
+  FRegister lo = static_cast<FRegister>(reg * 2);
+  FRegister hi = static_cast<FRegister>((reg * 2) + 1);
+  return Utils::LowHighTo64Bits(get_fregister(lo), get_fregister(hi));
+}
+
+
+double Simulator::get_dregister(DRegister reg) const {
+  ASSERT(reg >= 0);
+  ASSERT(reg < kNumberOfDRegisters);
+  const int64_t value = get_dregister_bits(reg);
+  return bit_cast<double, int64_t>(value);
+}
+
+
 void Simulator::UnimplementedInstruction(Instr* instr) {
   char buffer[64];
   snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr);
@@ -1097,10 +1131,9 @@
       int32_t rs_val = get_register(instr->RsField());
       int32_t rt_val = get_register(instr->RtField());
       if (rt_val == 0) {
-        // Results are unpredictable.
-        set_hi_register(0);
-        set_lo_register(0);
-        // TODO(zra): Drop into the debugger here.
+        // Results are unpredictable, but there is no arithmetic exception.
+        set_hi_register(icount_);
+        set_lo_register(icount_);
         break;
       }
 
@@ -1121,10 +1154,9 @@
       uint32_t rs_val = get_register(instr->RsField());
       uint32_t rt_val = get_register(instr->RtField());
       if (rt_val == 0) {
-        // Results are unpredictable.
-        set_hi_register(0);
-        set_lo_register(0);
-        // TODO(zra): Drop into the debugger here.
+        // Results are unpredictable, but there is no arithmetic exception.
+        set_hi_register(icount_);
+        set_lo_register(icount_);
         break;
       }
       set_lo_register(rs_val / rt_val);
@@ -1376,8 +1408,8 @@
       uint32_t lo = get_lo_register();
       uint32_t hi = get_hi_register();
       uint64_t accum = Utils::LowHighTo64Bits(lo, hi);
-      uint64_t rs = static_cast<int64_t>(get_register(instr->RsField()));
-      uint64_t rt = static_cast<int64_t>(get_register(instr->RtField()));
+      uint64_t rs = static_cast<uint64_t>(get_register(instr->RsField()));
+      uint64_t rt = static_cast<uint64_t>(get_register(instr->RtField()));
       uint64_t res = accum + rs * rt;
       set_hi_register(Utils::High32Bits(res));
       set_lo_register(Utils::Low32Bits(res));
@@ -1618,7 +1650,13 @@
         switch (instr->FormatField()) {
           case FMT_D: {
             double fs_dbl = get_fregister_double(instr->FsField());
-            int32_t fs_int = static_cast<int32_t>(fs_dbl);
+            int32_t fs_int;
+            if (isnan(fs_dbl) || isinf(fs_dbl) || (fs_dbl > INT_MAX) ||
+                (fs_dbl < INT_MIN)) {
+              fs_int = INT_MIN;
+            } else {
+              fs_int = static_cast<int32_t>(fs_dbl);
+            }
             set_fregister(instr->FdField(), fs_int);
             break;
           }
@@ -1630,6 +1668,22 @@
         }
         break;
       }
+      case COP1_CVT_S: {
+        switch (instr->FormatField()) {
+          case FMT_D: {
+            double fs_dbl = get_fregister_double(instr->FsField());
+            float fs_flt = static_cast<float>(fs_dbl);
+            set_fregister_float(instr->FdField(), fs_flt);
+            break;
+          }
+          default: {
+            OS::PrintErr("DecodeCop1: 0x%x\n", instr->InstructionBits());
+            UnimplementedInstruction(instr);
+            break;
+          }
+        }
+        break;
+      }
       default: {
         OS::PrintErr("DecodeCop1: 0x%x\n", instr->InstructionBits());
         UnimplementedInstruction(instr);
@@ -2021,15 +2075,24 @@
                         int32_t parameter0,
                         int32_t parameter1,
                         int32_t parameter2,
-                        int32_t parameter3) {
+                        int32_t parameter3,
+                        bool fp_return,
+                        bool fp_args) {
   // Save the SP register before the call so we can restore it.
   int32_t sp_before_call = get_register(SP);
 
   // Setup parameters.
-  set_register(A0, parameter0);
-  set_register(A1, parameter1);
-  set_register(A2, parameter2);
-  set_register(A3, parameter3);
+  if (fp_args) {
+    set_fregister(F0, parameter0);
+    set_fregister(F1, parameter1);
+    set_fregister(F2, parameter2);
+    set_fregister(F3, parameter3);
+  } else {
+    set_register(A0, parameter0);
+    set_register(A1, parameter1);
+    set_register(A2, parameter2);
+    set_register(A3, parameter3);
+  }
 
   // Make sure the activation frames are properly aligned.
   int32_t stack_pointer = sp_before_call;
@@ -2058,6 +2121,13 @@
   int32_t r22_val = get_register(R22);
   int32_t r23_val = get_register(R23);
 
+  double d10_val = get_dregister(D10);
+  double d11_val = get_dregister(D11);
+  double d12_val = get_dregister(D12);
+  double d13_val = get_dregister(D13);
+  double d14_val = get_dregister(D14);
+  double d15_val = get_dregister(D15);
+
   // Setup the callee-saved registers with a known value. To be able to check
   // that they are preserved properly across dart execution.
   int32_t callee_saved_value = icount_;
@@ -2070,6 +2140,13 @@
   set_register(R22, callee_saved_value);
   set_register(R23, callee_saved_value);
 
+  set_dregister_bits(D10, callee_saved_value);
+  set_dregister_bits(D11, callee_saved_value);
+  set_dregister_bits(D12, callee_saved_value);
+  set_dregister_bits(D13, callee_saved_value);
+  set_dregister_bits(D14, callee_saved_value);
+  set_dregister_bits(D15, callee_saved_value);
+
   // Start the simulation
   Execute();
 
@@ -2083,6 +2160,13 @@
   ASSERT(callee_saved_value == get_register(R22));
   ASSERT(callee_saved_value == get_register(R23));
 
+  ASSERT(callee_saved_value == get_dregister_bits(D10));
+  ASSERT(callee_saved_value == get_dregister_bits(D11));
+  ASSERT(callee_saved_value == get_dregister_bits(D12));
+  ASSERT(callee_saved_value == get_dregister_bits(D13));
+  ASSERT(callee_saved_value == get_dregister_bits(D14));
+  ASSERT(callee_saved_value == get_dregister_bits(D15));
+
   // Restore callee-saved registers with the original value.
   set_register(R16, r16_val);
   set_register(R17, r17_val);
@@ -2093,9 +2177,22 @@
   set_register(R22, r22_val);
   set_register(R23, r23_val);
 
+  set_dregister(D10, d10_val);
+  set_dregister(D11, d11_val);
+  set_dregister(D12, d12_val);
+  set_dregister(D13, d13_val);
+  set_dregister(D14, d14_val);
+  set_dregister(D15, d15_val);
+
   // Restore the SP register and return V1:V0.
   set_register(SP, sp_before_call);
-  return Utils::LowHighTo64Bits(get_register(V0), get_register(V1));
+  int64_t return_value;
+  if (fp_return) {
+    return_value = Utils::LowHighTo64Bits(get_fregister(F0), get_fregister(F1));
+  } else {
+    return_value = Utils::LowHighTo64Bits(get_register(V0), get_register(V1));
+  }
+  return return_value;
 }
 
 
@@ -2126,11 +2223,10 @@
   set_pc(static_cast<int32_t>(pc));
   set_register(SP, static_cast<int32_t>(sp));
   set_register(FP, static_cast<int32_t>(fp));
-  ASSERT(raw_exception != NULL);
+
+  ASSERT(raw_exception != Object::null());
   set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
-  if (raw_stacktrace != NULL) {
-    set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
-  }
+  set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
   buf->Longjmp();
 }
 
diff --git a/runtime/vm/simulator_mips.h b/runtime/vm/simulator_mips.h
index 9b685b2..db95370 100644
--- a/runtime/vm/simulator_mips.h
+++ b/runtime/vm/simulator_mips.h
@@ -50,6 +50,11 @@
   double get_fregister_double(FRegister freg) const;
   int64_t get_fregister_long(FRegister freg) const;
 
+  void set_dregister_bits(DRegister freg, int64_t value);
+  void set_dregister(DRegister freg, double value);
+
+  int64_t get_dregister_bits(DRegister freg) const;
+  double get_dregister(DRegister freg) const;
 
   // Accessor for the pc.
   void set_pc(int32_t value) { pc_ = value; }
@@ -95,12 +100,15 @@
 
   // Dart generally calls into generated code with 5 parameters. This is a
   // convenience function, which sets up the simulator state and grabs the
-  // result on return.
+  // result on return. When fp_return is true the return value is the D0
+  // floating point register. Otherwise, the return value is V1:V0.
   int64_t Call(int32_t entry,
                int32_t parameter0,
                int32_t parameter1,
                int32_t parameter2,
-               int32_t parameter3);
+               int32_t parameter3,
+               bool fp_return = false,
+               bool fp_args = false);
 
   // Runtime and native call support.
   enum CallKind {
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index 1a3b791..d634fe1 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -61,6 +61,7 @@
   V(ThreeArgsOptimizedCheckInlineCache)                                        \
   V(ClosureCallInlineCache)                                                    \
   V(MegamorphicCall)                                                           \
+  V(UnoptimizedStaticCall)                                                     \
   V(OptimizeFunction)                                                          \
   V(BreakpointDynamic)                                                         \
   V(EqualityWithNullArg)                                                       \
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 62314eb..6e26bd9 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1314,18 +1314,19 @@
 
 //  R6: function object.
 //  R5: inline cache data object.
-//  R4: arguments descriptor array.
+// Cannot use function object from ICData as it may be the inlined
+// function and not the top-scope function.
 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
   Register ic_reg = R5;
   Register func_reg = R6;
   if (FLAG_trace_optimized_ic_calls) {
     __ EnterStubFrame();
-    __ PushList((1 << R4) | (1 << R5) | (1 << R6));  // Preserve.
+    __ PushList((1 << R5) | (1 << R6));  // Preserve.
     __ Push(ic_reg);  // Argument.
     __ Push(func_reg);  // Argument.
     __ CallRuntime(kTraceICCallRuntimeEntry);
     __ Drop(2);  // Discard argument;
-    __ PushList((1 << R4) | (1 << R5) | (1 << R6));  // Restore.
+    __ PopList((1 << R5) | (1 << R6));  // Restore.
     __ LeaveStubFrame();
   }
   __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset()));
@@ -1372,7 +1373,6 @@
 // Generate inline cache check for 'num_args'.
 //  LR: return address.
 //  R5: inline cache data object.
-//  R4: arguments descriptor array.
 // Control flow:
 // - If receiver is null -> jump to IC miss.
 // - If receiver is Smi -> load Smi class.
@@ -1395,6 +1395,8 @@
   }
 #endif  // DEBUG
 
+  // Load arguments descriptor into R4.
+  __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
   // Preserve return address, since LR is needed for subroutine call.
   __ mov(R8, ShifterOperand(LR));
   // Loop that checks if there is an IC data match.
@@ -1536,7 +1538,6 @@
 // cache miss handler. Stub for 1-argument check (receiver class).
 //  LR: return address.
 //  R5: inline cache data object.
-//  R4: arguments descriptor array.
 // Inline cache data object structure:
 // 0: function-name
 // 1: N, number of arguments checked.
@@ -1592,29 +1593,95 @@
 }
 
 
+// Intermediary stub between a static call and its target. ICData contains
+// the target function and the call count.
+// R5: ICData
+void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+#if defined(DEBUG)
+  { Label ok;
+    // Check that the IC data array has NumberOfArgumentsChecked() == 0.
+    // 'num_args_tested' is stored as an untagged int.
+    __ ldr(R6, FieldAddress(R5, ICData::num_args_tested_offset()));
+    __ CompareImmediate(R6, 0);
+    __ b(&ok, EQ);
+    __ Stop("Incorrect IC data for unoptimized static call");
+    __ Bind(&ok);
+  }
+#endif  // DEBUG
+
+  // R5: IC data object (preserved).
+  __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
+  // R6: ic_data_array with entries: target functions and count.
+  __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag);
+  // R6: points directly to the first ic data array element.
+  const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
+  const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
+
+  // Increment count for this call.
+  Label increment_done;
+  __ LoadFromOffset(kLoadWord, R1, R6, count_offset);
+  __ adds(R1, R1, ShifterOperand(Smi::RawValue(1)));
+  __ StoreToOffset(kStoreWord, R1, R6, count_offset);
+  __ b(&increment_done, VC);  // No overflow.
+  __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue));
+  __ StoreToOffset(kStoreWord, R1, R6, count_offset);
+  __ Bind(&increment_done);
+
+  Label target_is_compiled;
+  // Get function and call it, if possible.
+  __ LoadFromOffset(kLoadWord, R1, R6, target_offset);
+  __ ldr(R0, FieldAddress(R1, Function::code_offset()));
+  __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
+  __ b(&target_is_compiled, NE);
+  // R1: function.
+
+  __ EnterStubFrame();
+  // Preserve target function and IC data object.
+  __ PushList((1 << R1) | (1 << R5));
+  __ Push(R1);  // Pass function.
+  __ CallRuntime(kCompileFunctionRuntimeEntry);
+  __ Drop(1);  // Discard argument.
+  __ PopList((1 << R1) | (1 << R5));  // Restore function and IC data.
+  __ LeaveStubFrame();
+  // R0: target function.
+  __ ldr(R0, FieldAddress(R1, Function::code_offset()));
+
+  __ Bind(&target_is_compiled);
+  // R0: target code.
+  __ ldr(R0, FieldAddress(R0, Code::instructions_offset()));
+  __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag);
+  // Load arguments descriptor into R4.
+  __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
+  __ bx(R0);
+}
+
+
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
   __ Unimplemented("BreakpointRuntime stub");
 }
 
 
 //  LR: return address (Dart code).
-//  R4: arguments descriptor array.
+//  R5: IC data (unoptimized static call).
 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();
   __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
   // Preserve arguments descriptor and make room for result.
-  __ PushList((1 << R0) | (1 << R4));
+  __ PushList((1 << R0) | (1 << R5));
   __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
   // Pop code object result and restore arguments descriptor.
-  __ PopList((1 << R0) | (1 << R4));
+  __ PopList((1 << R0) | (1 << R5));
   __ LeaveStubFrame();
 
   // Now call the static function. The breakpoint handler function
   // ensures that the call target is compiled.
   __ ldr(R0, FieldAddress(R0, Code::instructions_offset()));
   __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag);
+  // Load arguments descriptor into R4.
+  __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
   __ bx(R0);
 }
 
@@ -1638,14 +1705,13 @@
 
 //  LR: return address (Dart code).
 //  R5: inline cache data array.
-//  R4: arguments descriptor array.
 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();
-  __ PushList((1 << R4) | (1 << R5));
+  __ Push(R5);
   __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
-  __ PopList((1 << R4) | (1 << R5));
+  __ Pop(R5);
   __ LeaveStubFrame();
 
   // Find out which dispatch stub to call.
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 7f884622f..3797ffd 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1416,14 +1416,14 @@
 }
 
 
+// Cannot use function object from ICData as it may be the inlined
+// function and not the top-scope function.
 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
-  Register argdesc_reg = EDX;
   Register ic_reg = ECX;
   Register func_reg = EDI;
   if (FLAG_trace_optimized_ic_calls) {
     __ EnterStubFrame();
     __ pushl(func_reg);     // Preserve
-    __ pushl(argdesc_reg);  // Preserve.
     __ pushl(ic_reg);       // Preserve.
     __ pushl(ic_reg);       // Argument.
     __ pushl(func_reg);     // Argument.
@@ -1431,7 +1431,6 @@
     __ popl(EAX);          // Discard argument;
     __ popl(EAX);          // Discard argument;
     __ popl(ic_reg);       // Restore.
-    __ popl(argdesc_reg);  // Restore.
     __ popl(func_reg);     // Restore.
     __ LeaveFrame();
   }
@@ -1452,7 +1451,6 @@
 
 // Generate inline cache check for 'num_args'.
 //  ECX: Inline cache data object.
-//  EDX: Arguments descriptor array.
 //  TOS(0): return address
 // Control flow:
 // - If receiver is null -> jump to IC miss.
@@ -1476,6 +1474,8 @@
   }
 #endif  // DEBUG
 
+  // Load arguments descriptor into EDX.
+  __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
   // Loop that checks if there is an IC data match.
   Label loop, update, test, found, get_class_id_as_smi;
   // ECX: IC data object (preserved).
@@ -1581,7 +1581,7 @@
   const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
   __ movl(EAX, Address(EBX, target_offset));
   __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1)));
-  __ j(NO_OVERFLOW, &call_target_function);
+  __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump);
   __ movl(Address(EBX, count_offset),
           Immediate(Smi::RawValue(Smi::kMaxValue)));
 
@@ -1611,7 +1611,6 @@
 // Use inline cache data array to invoke the target or continue in inline
 // cache miss handler. Stub for 1-argument check (receiver class).
 //  ECX: Inline cache data object.
-//  EDX: Arguments descriptor array.
 //  TOS(0): Return address.
 // Inline cache data object structure:
 // 0: function-name
@@ -1641,7 +1640,6 @@
 // cache miss handler. Stub for 1-argument check (receiver class).
 //  EDI: function which counter needs to be incremented.
 //  ECX: Inline cache data object.
-//  EDX: Arguments descriptor array.
 //  TOS(0): Return address.
 // Inline cache data object structure:
 // 0: function-name
@@ -1682,6 +1680,66 @@
   GenerateNArgsCheckInlineCacheStub(assembler, 1);
 }
 
+// Intermediary stub between a static call and its target. ICData contains
+// the target function and the call count.
+// ECX: ICData
+void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, EBX);
+#if defined(DEBUG)
+  { Label ok;
+    // Check that the IC data array has NumberOfArgumentsChecked() == 0.
+    // 'num_args_tested' is stored as an untagged int.
+    __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
+    __ cmpl(EBX, Immediate(0));
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Incorrect IC data for unoptimized static call");
+    __ Bind(&ok);
+  }
+#endif  // DEBUG
+
+  // ECX: IC data object (preserved).
+  __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
+  // EBX: ic_data_array with entries: target functions and count.
+  __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
+  // EBX: points directly to the first ic data array element.
+  const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
+  const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
+
+  // Increment count for this call.
+  Label increment_done;
+  __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1)));
+  __ j(NO_OVERFLOW, &increment_done, Assembler::kNearJump);
+  __ movl(Address(EBX, count_offset), Immediate(Smi::RawValue(Smi::kMaxValue)));
+  __ Bind(&increment_done);
+
+  const Immediate& raw_null =
+      Immediate(reinterpret_cast<intptr_t>(Object::null()));
+  Label target_is_compiled;
+  // Get function and call it, if possible.
+  __ movl(EDI, Address(EBX, target_offset));
+  __ movl(EAX, FieldAddress(EDI, Function::code_offset()));
+  __ cmpl(EAX, raw_null);
+  __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump);
+  __ EnterStubFrame();
+  __ pushl(EDI);  // Preserve target function.
+  __ pushl(ECX);  // Preserve IC data object.
+  __ pushl(EDI);  // Pass function.
+  __ CallRuntime(kCompileFunctionRuntimeEntry);
+  __ popl(EAX);  // Discard argument.
+  __ popl(ECX);  // Restore IC data object.
+  __ popl(EDI);  // Restore target function.
+  __ LeaveFrame();
+  __ movl(EAX, FieldAddress(EDI, Function::code_offset()));
+
+  __ Bind(&target_is_compiled);
+  // EAX: Target code.
+  __ movl(EAX, FieldAddress(EAX, Code::instructions_offset()));
+  __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
+  // Load arguments descriptor into EDX.
+  __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
+  __ jmp(EAX);
+}
+
 
 // EDX, EXC: May contain arguments to runtime stub.
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
@@ -1703,21 +1761,23 @@
 }
 
 
-// EDX: Arguments descriptor array.
+// ECX: ICData (unoptimized static call).
 // TOS(0): return address (Dart code).
 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();
-  __ pushl(EDX);  // Preserve arguments descriptor.
+  __ pushl(ECX);  // Preserve ICData for unoptimized call.
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   __ pushl(raw_null);  // Room for result.
   __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
   __ popl(EAX);  // Code object.
-  __ popl(EDX);  // Restore arguments descriptor.
+  __ popl(ECX);  // Restore ICData.
   __ LeaveFrame();
 
+  // Load arguments descriptor into EDX.
+  __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
   // Now call the static function. The breakpoint handler function
   // ensures that the call target is compiled.
   // Note that we can't just jump to the CallStatic function stub
@@ -1749,16 +1809,13 @@
 
 
 //  ECX: Inline cache data array.
-//  EDX: Arguments descriptor array.
 //  TOS(0): return address (Dart code).
 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();
   __ pushl(ECX);
-  __ pushl(EDX);
   __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
-  __ popl(EDX);
   __ popl(ECX);
   __ LeaveFrame();
 
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 4bfd8a1..659a20b 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -1062,8 +1062,8 @@
   // Spilled: T1, T2, T3.
   // T0: Address being stored.
   __ lw(T2, FieldAddress(T0, Object::tags_offset()));
-  __ andi(T1, T2, Immediate(1 << RawObject::kRememberedBit));
-  __ beq(T1, ZR, &add_to_buffer);
+  __ andi(CMPRES, T2, Immediate(1 << RawObject::kRememberedBit));
+  __ beq(CMPRES, ZR, &add_to_buffer);
   __ lw(T1, Address(SP, 0 * kWordSize));
   __ lw(T2, Address(SP, 1 * kWordSize));
   __ lw(T3, Address(SP, 2 * kWordSize));
@@ -1092,7 +1092,7 @@
   // T2: top_
   // T1: StoreBufferBlock
   Label L;
-  __ AddImmediate(T2, 1);
+  __ addiu(T2, T2, Immediate(1));
   __ sw(T2, Address(T1, StoreBufferBlock::top_offset()));
   __ addiu(CMPRES, T2, Immediate(-StoreBufferBlock::kSize));
   // Restore values.
@@ -1107,7 +1107,7 @@
   __ Bind(&L);
   // Setup frame, push callee-saved registers.
 
-  __ EnterCallRuntimeFrame(0 * kWordSize);
+  __ EnterCallRuntimeFrame(1 * kWordSize);
   __ lw(A0, FieldAddress(CTX, Context::isolate_offset()));
   __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry);
   __ TraceSimMsg("UpdateStoreBufferStub return");
@@ -1489,24 +1489,23 @@
 
 //  T0: function object.
 //  S5: inline cache data object.
-//  S4: arguments descriptor array.
+// Cannot use function object from ICData as it may be the inlined
+// function and not the top-scope function.
 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
   __ TraceSimMsg("OptimizedUsageCounterIncrement");
   Register ic_reg = S5;
   Register func_reg = T0;
   if (FLAG_trace_optimized_ic_calls) {
     __ EnterStubFrame();
-    __ addiu(SP, SP, Immediate(-5 * kWordSize));
-    __ sw(T0, Address(SP, 4 * kWordSize));
-    __ sw(S5, Address(SP, 3 * kWordSize));
-    __ sw(S4, Address(SP, 2 * kWordSize));  // Preserve.
+    __ addiu(SP, SP, Immediate(-4 * kWordSize));
+    __ sw(T0, Address(SP, 3 * kWordSize));
+    __ sw(S5, Address(SP, 2 * kWordSize));
     __ sw(ic_reg, Address(SP, 1 * kWordSize));  // Argument.
     __ sw(func_reg, Address(SP, 0 * kWordSize));  // Argument.
     __ CallRuntime(kTraceICCallRuntimeEntry);
-    __ lw(S4, Address(SP, 2 * kWordSize));  // Restore.
-    __ lw(S5, Address(SP, 3 * kWordSize));
-    __ lw(T0, Address(SP, 4 * kWordSize));
-    __ addiu(SP, SP, Immediate(5 * kWordSize));  // Discard argument;
+    __ lw(S5, Address(SP, 2 * kWordSize));
+    __ lw(T0, Address(SP, 3 * kWordSize));
+    __ addiu(SP, SP, Immediate(4 * kWordSize));  // Discard argument;
     __ LeaveStubFrame();
   }
   __ lw(T7, FieldAddress(func_reg, Function::usage_counter_offset()));
@@ -1553,7 +1552,6 @@
 // Generate inline cache check for 'num_args'.
 //  RA: return address
 //  S5: Inline cache data object.
-//  S4: Arguments descriptor array.
 // Control flow:
 // - If receiver is null -> jump to IC miss.
 // - If receiver is Smi -> load Smi class.
@@ -1576,6 +1574,8 @@
   }
 #endif  // DEBUG
 
+  // Load argument descriptor into S4.
+  __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
   // Preserve return address, since RA is needed for subroutine call.
   __ mov(T2, RA);
   // Loop that checks if there is an IC data match.
@@ -1743,7 +1743,6 @@
 // cache miss handler. Stub for 1-argument check (receiver class).
 //  RA: Return address.
 //  S5: Inline cache data object.
-//  S4: Arguments descriptor array.
 // Inline cache data object structure:
 // 0: function-name
 // 1: N, number of arguments checked.
@@ -1799,13 +1798,83 @@
 }
 
 
+// Intermediary stub between a static call and its target. ICData contains
+// the target function and the call count.
+// S5: ICData
+void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, T0);
+  __ TraceSimMsg("UnoptimizedStaticCallStub");
+#if defined(DEBUG)
+  { Label ok;
+    // Check that the IC data array has NumberOfArgumentsChecked() == 0.
+    // 'num_args_tested' is stored as an untagged int.
+    __ lw(T0, FieldAddress(S5, ICData::num_args_tested_offset()));
+    __ beq(T0, ZR, &ok);
+    __ Stop("Incorrect IC data for unoptimized static call");
+    __ Bind(&ok);
+  }
+#endif  // DEBUG
+
+  // S5: IC data object (preserved).
+  __ lw(T0, FieldAddress(S5, ICData::ic_data_offset()));
+  // T0: ic_data_array with entries: target functions and count.
+  __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag);
+  // T0: points directly to the first ic data array element.
+  const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
+  const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
+
+  // Increment count for this call.
+  Label increment_done;
+  __ lw(T4, Address(T0, count_offset));
+  __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6);
+  __ bgez(T5, &increment_done);  // No overflow.
+  __ delay_slot()->sw(T4, Address(T0, count_offset));
+
+  __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue));
+  __ sw(T1, Address(T0, count_offset));
+
+  __ Bind(&increment_done);
+
+  Label target_is_compiled;
+  // Get function and call it, if possible.
+  __ lw(T3, Address(T0, target_offset));
+  __ lw(T4, FieldAddress(T3, Function::code_offset()));
+  __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
+  __ bne(T4, TMP, &target_is_compiled);
+
+  __ EnterStubFrame();
+  // Preserve target function and IC data object.
+  // Two preserved registers, one argument (function) => 3 slots.
+  __ addiu(SP, SP, Immediate(-3 * kWordSize));
+  __ sw(S5, Address(SP, 2 * kWordSize));  // Preserve IC data.
+  __ sw(T3, Address(SP, 1 * kWordSize));  // Preserve function.
+  __ sw(T3, Address(SP, 0 * kWordSize));  // Function argument.
+  __ CallRuntime(kCompileFunctionRuntimeEntry);
+  __ lw(T3, Address(SP, 1 * kWordSize));  // Restore function.
+  __ lw(S5, Address(SP, 2 * kWordSize));  // Restore IC data.
+  __ addiu(SP, SP, Immediate(3 * kWordSize));
+  // T3: target function.
+  __ lw(T4, FieldAddress(T3, Function::code_offset()));
+  __ LeaveStubFrame();
+
+  __ Bind(&target_is_compiled);
+  // T4: target code.
+  __ lw(T3, FieldAddress(T4, Code::instructions_offset()));
+  __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag);
+  __ jr(T3);
+  // Load arguments descriptor into S4.
+  __ delay_slot()->
+      lw(S4,  FieldAddress(S5, ICData::arguments_descriptor_offset()));
+}
+
+
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
   __ Unimplemented("BreakpointRuntime stub");
 }
 
 
 //  RA: return address (Dart code).
-//  S4: Arguments descriptor array.
+//  S5: IC data (unoptimized static call).
 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
   __ TraceSimMsg("BreakpointStaticStub");
   // Create a stub frame as we are pushing some objects on the stack before
@@ -1813,13 +1882,13 @@
   __ EnterStubFrame();
   // Preserve arguments descriptor and make room for result.
   __ addiu(SP, SP, Immediate(-2 * kWordSize));
-  __ sw(S4, Address(SP, 1 * kWordSize));
+  __ sw(S5, Address(SP, 1 * kWordSize));
   __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
   __ sw(TMP, Address(SP, 0 * kWordSize));
   __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
   // Pop code object result and restore arguments descriptor.
   __ lw(T0, Address(SP, 0 * kWordSize));
-  __ lw(S4, Address(SP, 1 * kWordSize));
+  __ lw(S5, Address(SP, 1 * kWordSize));
   __ addiu(SP, SP, Immediate(2 * kWordSize));
   __ LeaveStubFrame();
 
@@ -1827,6 +1896,8 @@
   // ensures that the call target is compiled.
   __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
   __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
+  // Load arguments descriptor into S4.
+  __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
   __ jr(T0);
 }
 
@@ -1850,19 +1921,14 @@
 
 //  RA: return address (Dart code).
 //  S5: Inline cache data array.
-//  S4: Arguments descriptor array.
 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ TraceSimMsg("BreakpointDynamicStub");
   __ EnterStubFrame();
-  __ addiu(SP, SP, Immediate(-2 * kWordSize));
-  __ sw(S5, Address(SP, 1 * kWordSize));
-  __ sw(S4, Address(SP, 0 * kWordSize));
+  __ Push(S5);
   __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
-  __ lw(S4, Address(SP, 0 * kWordSize));
-  __ lw(S5, Address(SP, 1 * kWordSize));
-  __ addiu(SP, SP, Immediate(2 * kWordSize));
+  __ Pop(S5);
   __ LeaveStubFrame();
 
   // Find out which dispatch stub to call.
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 8d78a52..97e2bbc 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1399,14 +1399,14 @@
 }
 
 
+// Cannot use function object from ICData as it may be the inlined
+// function and not the top-scope function.
 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
-  Register argdesc_reg = R10;
   Register ic_reg = RBX;
   Register func_reg = RDI;
   if (FLAG_trace_optimized_ic_calls) {
     __ EnterStubFrame();
     __ pushq(func_reg);     // Preserve
-    __ pushq(argdesc_reg);  // Preserve.
     __ pushq(ic_reg);       // Preserve.
     __ pushq(ic_reg);       // Argument.
     __ pushq(func_reg);     // Argument.
@@ -1414,7 +1414,6 @@
     __ popq(RAX);          // Discard argument;
     __ popq(RAX);          // Discard argument;
     __ popq(ic_reg);       // Restore.
-    __ popq(argdesc_reg);  // Restore.
     __ popq(func_reg);     // Restore.
     __ LeaveFrame();
   }
@@ -1435,7 +1434,6 @@
 
 // Generate inline cache check for 'num_args'.
 //  RBX: Inline cache data object.
-//  R10: Arguments descriptor array.
 //  TOS(0): return address
 // Control flow:
 // - If receiver is null -> jump to IC miss.
@@ -1459,6 +1457,8 @@
   }
 #endif  // DEBUG
 
+  // Load arguments descriptor into R10.
+  __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
   // Loop that checks if there is an IC data match.
   Label loop, update, test, found, get_class_id_as_smi;
   // RBX: IC data object (preserved).
@@ -1562,7 +1562,7 @@
   const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
   __ movq(RAX, Address(R12, target_offset));
   __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1)));
-  __ j(NO_OVERFLOW, &call_target_function);
+  __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump);
   __ movq(Address(R12, count_offset),
           Immediate(Smi::RawValue(Smi::kMaxValue)));
 
@@ -1591,7 +1591,6 @@
 // Use inline cache data array to invoke the target or continue in inline
 // cache miss handler. Stub for 1-argument check (receiver class).
 //  RBX: Inline cache data object.
-//  R10: Arguments descriptor array.
 //  TOS(0): Return address.
 // Inline cache data object structure:
 // 0: function-name
@@ -1620,7 +1619,6 @@
 // cache miss handler. Stub for 1-argument check (receiver class).
 //  RDI: function which counter needs to be incremented.
 //  RBX: Inline cache data object.
-//  R10: Arguments descriptor array.
 //  TOS(0): Return address.
 // Inline cache data object structure:
 // 0: function-name
@@ -1662,6 +1660,69 @@
 }
 
 
+// Intermediary stub between a static call and its target. ICData contains
+// the target function and the call count.
+// RBX: ICData
+void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+#if defined(DEBUG)
+  { Label ok;
+    // Check that the IC data array has NumberOfArgumentsChecked() == 0.
+    // 'num_args_tested' is stored as an untagged int.
+    __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset()));
+    __ cmpq(RCX, Immediate(0));
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Incorrect IC data for unoptimized static call");
+    __ Bind(&ok);
+  }
+#endif  // DEBUG
+
+  // RBX: IC data object (preserved).
+  __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
+  // R12: ic_data_array with entries: target functions and count.
+  __ leaq(R12, FieldAddress(R12, Array::data_offset()));
+  // R12: points directly to the first ic data array element.
+  const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
+  const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
+
+  // Increment count for this call.
+  Label increment_done;
+  __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1)));
+  __ j(NO_OVERFLOW, &increment_done, Assembler::kNearJump);
+  __ movq(Address(R12, count_offset),
+          Immediate(Smi::RawValue(Smi::kMaxValue)));
+  __ Bind(&increment_done);
+
+  const Immediate& raw_null =
+      Immediate(reinterpret_cast<intptr_t>(Object::null()));
+  Label target_is_compiled;
+  // Get function and call it, if possible.
+  __ movq(R13, Address(R12, target_offset));
+  __ movq(RAX, FieldAddress(R13, Function::code_offset()));
+  __ cmpq(RAX, raw_null);
+  __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump);
+
+  __ EnterStubFrame();
+  __ pushq(R13);  // Preserve target function.
+  __ pushq(RBX);  // Preserve IC data object.
+  __ pushq(R13);  // Pass function.
+  __ CallRuntime(kCompileFunctionRuntimeEntry);
+  __ popq(RAX);  // Discard argument.
+  __ popq(RBX);  // Restore IC data object.
+  __ popq(R13);  // Restore target function.
+  __ LeaveFrame();
+  __ movq(RAX, FieldAddress(R13, Function::code_offset()));
+
+  __ Bind(&target_is_compiled);
+  // RAX: Target code.
+  __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
+  __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
+  // Load arguments descriptor into R10.
+  __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
+  __ jmp(RAX);
+}
+
+
 //  RBX, R10: May contain arguments to runtime stub.
 //  TOS(0): return address (Dart code).
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
@@ -1683,19 +1744,21 @@
 }
 
 
-//  R10: Arguments descriptor array.
+//  RBX: ICData (unoptimized static call)
 //  TOS(0): return address (Dart code).
 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   __ EnterStubFrame();
-  __ pushq(R10);  // Preserve arguments descriptor.
+  __ pushq(RBX);  // Preserve IC data for unoptimized call.
   __ pushq(raw_null);  // Room for result.
   __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
   __ popq(RAX);  // Code object.
-  __ popq(R10);  // Restore arguments descriptor.
+  __ popq(RBX);  // Restore IC data.
   __ LeaveFrame();
 
+  // Load arguments descriptor into R10.
+  __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
   // Now call the static function. The breakpoint handler function
   // ensures that the call target is compiled.
   __ movq(RBX, FieldAddress(RAX, Code::instructions_offset()));
@@ -1719,14 +1782,11 @@
 
 
 //  RBX: Inline cache data array.
-//  R10: Arguments descriptor array.
 //  TOS(0): return address (Dart code).
 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
   __ EnterStubFrame();
   __ pushq(RBX);
-  __ pushq(R10);
   __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
-  __ popq(R10);
   __ popq(RBX);
   __ LeaveFrame();
 
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 2688745..0fb42e2 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -226,7 +226,7 @@
   V(NullThrownError, "NullThrownError")                                        \
   V(IsolateSpawnException, "IsolateSpawnException")                            \
   V(IsolateUnhandledException, "IsolateUnhandledException")                    \
-  V(FiftyThreeBitOverflowError, "FiftyThreeBitOverflowError")                  \
+  V(FiftyThreeBitOverflowError, "_FiftyThreeBitOverflowError")                 \
   V(_setupFullStackTrace, "_setupFullStackTrace")                              \
   V(BooleanExpression, "boolean expression")                                   \
   V(Malformed, "malformed")                                                    \
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 8f674c7..2ca6293 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -156,21 +156,21 @@
       Utils::High32Bits(long_arg1)))
 #define EXECUTE_TEST_CODE_FLOAT(name, entry)                                   \
   bit_cast<float, int32_t>(Simulator::Current()->Call(                         \
-      bit_cast<int32_t, uword>(entry), 0, 0, 0, 0))
+      bit_cast<int32_t, uword>(entry), 0, 0, 0, 0, true))
 #define EXECUTE_TEST_CODE_DOUBLE(name, entry)                                  \
   bit_cast<double, int64_t>(Simulator::Current()->Call(                        \
-      bit_cast<int32_t, uword>(entry), 0, 0, 0, 0))
+      bit_cast<int32_t, uword>(entry), 0, 0, 0, 0, true))
 #define EXECUTE_TEST_CODE_INT32_F(name, entry, float_arg)                      \
   static_cast<int32_t>(Simulator::Current()->Call(                             \
       bit_cast<int32_t, uword>(entry),                                         \
       bit_cast<int32_t, float>(float_arg),                                     \
-      0, 0, 0))
+      0, 0, 0, false, true))
 #define EXECUTE_TEST_CODE_INT32_D(name, entry, double_arg)                     \
   static_cast<int32_t>(Simulator::Current()->Call(                             \
       bit_cast<int32_t, uword>(entry),                                         \
       Utils::Low32Bits(bit_cast<int64_t, double>(double_arg)),                 \
       Utils::High32Bits(bit_cast<int64_t, double>(double_arg)),                \
-      0, 0))
+      0, 0, false, true))
 #endif  // defined(HOST_ARCH_ARM) || defined(HOST_ARCH_MIPS)
 #endif  // defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
 
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index 1e1da59..3e0311a 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -4,7 +4,7 @@
 
 {
   'variables': {
-    'gen_source_dir': '<(LIB_DIR)',
+    'gen_source_dir': '<(SHARED_INTERMEDIATE_DIR)',
     'libgen_in_cc_file': '../lib/libgen_in.cc',
     'builtin_in_cc_file': '../bin/builtin_in.cc',
     'async_cc_file': '<(gen_source_dir)/async_gen.cc',
@@ -93,25 +93,25 @@
       'type': 'static_library',
       'toolsets':['host', 'target'],
       'dependencies': [
-        'generate_async_cc_file',
-        'generate_async_patch_cc_file',
-        'generate_corelib_cc_file',
-        'generate_corelib_patch_cc_file',
-        'generate_collection_cc_file',
-        'generate_collection_patch_cc_file',
-        'generate_collection_dev_cc_file',
-        'generate_collection_dev_patch_cc_file',
-        'generate_math_cc_file',
-        'generate_math_patch_cc_file',
-        'generate_isolate_cc_file',
-        'generate_isolate_patch_cc_file',
-        'generate_json_cc_file',
-        'generate_json_patch_cc_file',
-        'generate_mirrors_cc_file',
-        'generate_mirrors_patch_cc_file',
-        'generate_typed_data_cc_file',
-        'generate_typed_data_patch_cc_file',
-        'generate_utf_cc_file',
+        'generate_async_cc_file#host',
+        'generate_async_patch_cc_file#host',
+        'generate_corelib_cc_file#host',
+        'generate_corelib_patch_cc_file#host',
+        'generate_collection_cc_file#host',
+        'generate_collection_patch_cc_file#host',
+        'generate_collection_dev_cc_file#host',
+        'generate_collection_dev_patch_cc_file#host',
+        'generate_math_cc_file#host',
+        'generate_math_patch_cc_file#host',
+        'generate_isolate_cc_file#host',
+        'generate_isolate_patch_cc_file#host',
+        'generate_json_cc_file#host',
+        'generate_json_patch_cc_file#host',
+        'generate_mirrors_cc_file#host',
+        'generate_mirrors_patch_cc_file#host',
+        'generate_typed_data_cc_file#host',
+        'generate_typed_data_patch_cc_file#host',
+        'generate_utf_cc_file#host',
       ],
       'includes': [
         '../lib/async_sources.gypi',
@@ -172,7 +172,7 @@
     {
       'target_name': 'generate_async_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         '../../sdk/lib/async/async_sources.gypi',
       ],
@@ -211,7 +211,7 @@
     {
       'target_name': 'generate_corelib_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the shared core library sources.
         '../../sdk/lib/core/corelib_sources.gypi',
@@ -251,7 +251,7 @@
     {
       'target_name': 'generate_corelib_patch_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the runtime implementation sources.
         '../lib/corelib_sources.gypi',
@@ -291,7 +291,7 @@
     {
       'target_name': 'generate_collection_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the shared collection library sources.
         '../../sdk/lib/collection/collection_sources.gypi',
@@ -331,7 +331,7 @@
     {
       'target_name': 'generate_collection_dev_patch_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the runtime implementation sources.
         '../lib/collection_dev_sources.gypi',
@@ -371,7 +371,7 @@
     {
       'target_name': 'generate_collection_dev_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the shared collection_dev library sources.
         '../../sdk/lib/_collection_dev/collection_dev_sources.gypi',
@@ -411,7 +411,7 @@
     {
       'target_name': 'generate_math_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the shared math library sources.
         '../../sdk/lib/math/math_sources.gypi',
@@ -451,7 +451,7 @@
     {
       'target_name': 'generate_math_patch_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the shared math library sources.
         '../lib/math_sources.gypi',
@@ -491,7 +491,7 @@
     {
       'target_name': 'generate_mirrors_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the shared core library sources.
         '../../sdk/lib/mirrors/mirrors_sources.gypi',
@@ -531,7 +531,7 @@
     {
       'target_name': 'generate_mirrors_patch_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the patch sources.
         '../lib/mirrors_sources.gypi',
@@ -571,7 +571,7 @@
     {
       'target_name': 'generate_isolate_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the runtime implementation sources.
         '../../sdk/lib/isolate/isolate_sources.gypi',
@@ -611,7 +611,7 @@
     {
       'target_name': 'generate_async_patch_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the runtime implementation sources.
         '../lib/async_sources.gypi',
@@ -651,7 +651,7 @@
     {
       'target_name': 'generate_collection_patch_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the runtime implementation sources.
         '../lib/collection_sources.gypi',
@@ -691,7 +691,7 @@
     {
       'target_name': 'generate_isolate_patch_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the runtime implementation sources.
         '../lib/isolate_sources.gypi',
@@ -731,7 +731,7 @@
     {
       'target_name': 'generate_json_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the shared json sources.
         '../../sdk/lib/json/json_sources.gypi',
@@ -764,7 +764,7 @@
     {
       'target_name': 'generate_json_patch_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the shared json library sources.
         '../lib/json_sources.gypi',
@@ -804,7 +804,7 @@
     {
       'target_name': 'generate_typed_data_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the shared library sources.
         '../../sdk/lib/typed_data/typed_data_sources.gypi',
@@ -844,7 +844,7 @@
     {
       'target_name': 'generate_typed_data_patch_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the runtime implementation sources.
         '../lib/typed_data_sources.gypi',
@@ -884,7 +884,7 @@
     {
       'target_name': 'generate_utf_cc_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'includes': [
         # Load the shared utf sources.
         '../../sdk/lib/utf/utf_sources.gypi',
@@ -917,7 +917,7 @@
     {
       'target_name': 'generate_snapshot_test_dat_file',
       'type': 'none',
-      'toolsets':['host', 'target'],
+      'toolsets':['host'],
       'actions': [
         {
           'action_name': 'generate_snapshot_test_dat',
diff --git a/sdk/bin/pub b/sdk/bin/pub
index 3643085..231da3e 100755
--- a/sdk/bin/pub
+++ b/sdk/bin/pub
@@ -17,7 +17,7 @@
 if test -f "$SNAPSHOT"; then
   # We are running the snapshot in the built SDK.
   DART="$BIN_DIR/dart"
-  exec "$DART" "--checked" "$SNAPSHOT" "$@"
+  exec "$DART" "$SNAPSHOT" "$@"
 else
   # We are running pub from source in the development repo.
   if [ -z "$DART_CONFIGURATION" ];
@@ -39,5 +39,5 @@
 
   PUB="$SDK_DIR/lib/_internal/pub/bin/pub.dart"
 
-  exec "$DART" "--checked" "--package-root=$PACKAGES_DIR" "$PUB" "$@"
+  exec "$DART" "--package-root=$PACKAGES_DIR" "$PUB" "$@"
 fi
\ No newline at end of file
diff --git a/sdk/bin/pub.bat b/sdk/bin/pub.bat
index 6f0d4e0..03213fd 100644
--- a/sdk/bin/pub.bat
+++ b/sdk/bin/pub.bat
@@ -25,9 +25,9 @@
 set SNAPSHOT=%BIN_DIR%\snapshots\pub.dart.snapshot
 
 if exist "%SNAPSHOT%" (
-  "%DART%" --checked "%SNAPSHOT%" %*
+  "%DART%" "%SNAPSHOT%" %*
 ) else (
-  "%DART_IN_BUILT_SDK%" --checked --package-root=%PACKAGES_DIR% "%PUB%" %*
+  "%DART_IN_BUILT_SDK%" --package-root=%PACKAGES_DIR% "%PUB%" %*
 )
 
 endlocal
diff --git a/sdk/bin/pub_developer b/sdk/bin/pub_developer
new file mode 100755
index 0000000..be0510d9
--- /dev/null
+++ b/sdk/bin/pub_developer
@@ -0,0 +1,43 @@
+#!/bin/bash
+# Copyright (c) 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.
+
+# Run pub.dart on the Dart VM. This script assumes the Dart SDK's directory
+# structure.
+
+# Setting BIN_DIR this way is ugly, but is needed to handle the case where
+# dart-sdk/bin has been symlinked to. On MacOS, readlink doesn't work
+# with this case.
+BIN_DIR="$(cd "${0%/*}" ; pwd -P)"
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot"
+
+if test -f "$SNAPSHOT"; then
+  # We are running the snapshot in the built SDK.
+  DART="$BIN_DIR/dart"
+  exec "$DART" --checked "$SNAPSHOT" "$@"
+else
+  # We are running pub from source in the development repo.
+  if [ -z "$DART_CONFIGURATION" ];
+  then
+    DART_CONFIGURATION="ReleaseIA32"
+  fi
+
+  if [[ `uname` == 'Darwin' ]];
+  then
+    BUILD_DIR="$SDK_DIR/../xcodebuild/$DART_CONFIGURATION"
+  else
+    BUILD_DIR="$SDK_DIR/../out/$DART_CONFIGURATION"
+  fi
+
+  # Use the Dart binary in the built SDK so pub can find the version file next
+  # to it.
+  DART="$BUILD_DIR/dart-sdk/bin/dart"
+  PACKAGES_DIR="$BUILD_DIR/packages/"
+
+  PUB="$SDK_DIR/lib/_internal/pub/bin/pub.dart"
+
+  exec "$DART" "--checked" "--package-root=$PACKAGES_DIR" "$PUB" "$@"
+fi
\ No newline at end of file
diff --git a/sdk/bin/pub_developer.bat b/sdk/bin/pub_developer.bat
new file mode 100644
index 0000000..6f0d4e0
--- /dev/null
+++ b/sdk/bin/pub_developer.bat
@@ -0,0 +1,49 @@
+@echo off
+REM Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+REM for details. All rights reserved. Use of this source code is governed by a
+REM BSD-style license that can be found in the LICENSE file.
+
+setlocal
+rem Handle the case where dart-sdk/bin has been symlinked to.
+set DIR_NAME_WITH_SLASH=%~dp0
+set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%%
+call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR
+rem Get rid of surrounding quotes.
+for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi
+
+rem Get absolute full name for SDK_DIR.
+for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi
+
+rem Remove trailing backslash if there is one
+IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1%
+
+set PUB=%SDK_DIR%\lib\_internal\pub\bin\pub.dart
+set BUILD_DIR=%SDK_DIR%\..\build\ReleaseIA32
+set PACKAGES_DIR=%BUILD_DIR%\packages\
+set DART=%BIN_DIR%\dart
+set DART_IN_BUILT_SDK=%BUILD_DIR%\dart-sdk\bin\dart
+set SNAPSHOT=%BIN_DIR%\snapshots\pub.dart.snapshot
+
+if exist "%SNAPSHOT%" (
+  "%DART%" --checked "%SNAPSHOT%" %*
+) else (
+  "%DART_IN_BUILT_SDK%" --checked --package-root=%PACKAGES_DIR% "%PUB%" %*
+)
+
+endlocal
+
+exit /b %errorlevel%
+
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "tokens=2 delims=[]" %%i in ('dir /a:l ^"%~dp1^" 2^>nul ^
+                                     ^| find ">     %~n1 ["') do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk/lib/_collection_dev/iterable.dart b/sdk/lib/_collection_dev/iterable.dart
index a6a65b2..53b297f 100644
--- a/sdk/lib/_collection_dev/iterable.dart
+++ b/sdk/lib/_collection_dev/iterable.dart
@@ -46,7 +46,7 @@
     return elementAt(0);
   }
 
-  bool contains(E element) {
+  bool contains(Object element) {
     int length = this.length;
     for (int i = 0; i < length; i++) {
       if (elementAt(i) == element) return true;
@@ -79,7 +79,7 @@
     return false;
   }
 
-  E firstWhere(bool test(E element), { E orElse() }) {
+  dynamic firstWhere(bool test(E element), { Object orElse() }) {
     int length = this.length;
     for (int i = 0; i < length; i++) {
       E element = elementAt(i);
@@ -92,7 +92,7 @@
     throw new StateError("No matching element");
   }
 
-  E lastWhere(bool test(E element), { E orElse() }) {
+  dynamic lastWhere(bool test(E element), { Object orElse() }) {
     int length = this.length;
     for (int i = length - 1; i >= 0; i--) {
       E element = elementAt(i);
@@ -216,7 +216,19 @@
   /** If null, represents the length of the iterable. */
   final int _endOrLength;
 
-  SubListIterable(this._iterable, this._start, this._endOrLength);
+  SubListIterable(this._iterable, this._start, this._endOrLength) {
+    if (_start < 0) {
+      throw new RangeError.value(_start);
+    }
+    if (_endOrLength != null) {
+      if (_endOrLength < 0) {
+        throw new RangeError.value(_endOrLength);
+      }
+      if (_start > _endOrLength) {
+        throw new RangeError.range(_start, 0, _endOrLength);
+      }
+    }
+  }
 
   int get _endIndex {
     int length = _iterable.length;
@@ -248,12 +260,12 @@
   }
 
   Iterable<E> skip(int count) {
-    if (count < 0) throw new ArgumentError(count);
+    if (count < 0) throw new RangeError.value(count);
     return new SubListIterable(_iterable, _start + count, _endOrLength);
   }
 
   Iterable<E> take(int count) {
-    if (count < 0) throw new ArgumentError(count);
+    if (count < 0) throw new RangeError.value(count);
     if (_endOrLength == null) {
       return new SubListIterable(_iterable, _start, _start + count);
     } else {
@@ -518,13 +530,13 @@
 
   SkipIterable(this._iterable, this._skipCount) {
     if (_skipCount is! int || _skipCount < 0) {
-      throw new ArgumentError(_skipCount);
+      throw new RangeError(_skipCount);
     }
   }
 
   Iterable<E> skip(int n) {
     if (n is! int || n < 0) {
-      throw new ArgumentError(n);
+      throw new RangeError.value(n);
     }
     return new SkipIterable<E>(_iterable, _skipCount + n);
   }
@@ -608,7 +620,7 @@
 
   E elementAt(int index) { throw new RangeError.value(index); }
 
-  bool contains(E element) => false;
+  bool contains(Object element) => false;
 
   bool every(bool test(E element)) => true;
 
@@ -643,11 +655,17 @@
     return initialValue;
   }
 
-  Iterable<E> skip(int count) => this;
+  Iterable<E> skip(int count) {
+    if (count < 0) throw new RangeError.value(count);
+    return this;
+  }
 
   Iterable<E> skipWhile(bool test(E element)) => this;
 
-  Iterable<E> take(int count) => this;
+  Iterable<E> take(int count) {
+    if (count < 0) throw new RangeError.value(count);
+    this;
+  }
 
   Iterable<E> takeWhile(bool test(E element)) => this;
 
@@ -780,8 +798,8 @@
   }
 
   static dynamic firstWhere(Iterable iterable,
-                               bool test(dynamic value),
-                               dynamic orElse()) {
+                            bool test(dynamic value),
+                            dynamic orElse()) {
     for (dynamic element in iterable) {
       if (test(element)) return element;
     }
diff --git a/sdk/lib/_collection_dev/list.dart b/sdk/lib/_collection_dev/list.dart
index 90a1d16..7f894bb 100644
--- a/sdk/lib/_collection_dev/list.dart
+++ b/sdk/lib/_collection_dev/list.dart
@@ -35,7 +35,7 @@
         "Cannot add to a fixed-length list");
   }
 
-  bool remove(E element) {
+  bool remove(Object element) {
     throw new UnsupportedError(
         "Cannot remove from a fixed-length list");
   }
@@ -130,7 +130,7 @@
         "Cannot add to an unmodifiable list");
   }
 
-  bool remove(E element) {
+  bool remove(Object element) {
     throw new UnsupportedError(
         "Cannot remove from an unmodifiable list");
   }
@@ -239,7 +239,7 @@
 
   bool get isEmpty => _values.isEmpty;
   bool get isNotEmpty => _values.isNotEmpty;
-  bool containsValue(E value) => _values.contains(value);
+  bool containsValue(Object value) => _values.contains(value);
   bool containsKey(int key) => key is int && key >= 0 && key < length;
 
   void forEach(void f(int key, E value)) {
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index 35b227e..3815390 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -477,12 +477,12 @@
         // capture them in the closure.
         type.forEachTypeVariable((variable) => useLocal(variable.element));
       }
-      // TODO(karlklose): try to get rid of the isField check; there is a bug
-      // with type variable use in field initializer (in both modes).
       if (member.isInstanceMember() && !member.isField()) {
         // In checked mode, using a type variable in a type annotation may lead
         // to a runtime type check that needs to access the type argument and
-        // therefore the closure needs a this-element.
+        // therefore the closure needs a this-element, if it is not in a field
+        // initializer; field initatializers are evaluated in a context where
+        // the type arguments are available in locals.
         registerNeedsThis();
       }
     }
@@ -509,6 +509,12 @@
       registerNeedsThis();
     } else if (node.isSuperCall) {
       registerNeedsThis();
+    } else if (node.isIsCheck || node.isIsNotCheck || node.isTypeCast) {
+      TypeAnnotation annotation = node.typeAnnotationFromIsCheckOrCast;
+      DartType type = elements.getType(annotation);
+      if (type != null && type.containsTypeVariables) {
+        registerNeedsThis();
+      }
     } else if (node.isParameterCheck) {
       Element parameter = elements[node.receiver];
       FunctionElement enclosing = parameter.enclosingElement;
@@ -523,6 +529,12 @@
         useLocal(newElement);
         cached.parametersWithSentinel[parameter] = newElement;
       }
+    } else if (node.isTypeTest) {
+      DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
+      analyzeType(type);
+    } else if (node.isTypeCast) {
+      DartType type = elements.getType(node.arguments.head);
+      analyzeType(type);
     }
     node.visitChildren(this);
   }
@@ -541,44 +553,35 @@
 
   visitNewExpression(NewExpression node) {
     DartType type = elements.getType(node);
+    analyzeType(type);
+    node.visitChildren(this);
+  }
 
-    bool hasTypeVariable(DartType type) {
-      if (type is TypeVariableType) {
-        return true;
-      } else if (type is InterfaceType) {
-        InterfaceType ifcType = type;
-        for (DartType argument in ifcType.typeArguments) {
-          if (hasTypeVariable(argument)) {
-            return true;
-          }
-        }
+  void analyzeTypeVariables(DartType type) {
+    type.forEachTypeVariable((TypeVariableType typeVariable) {
+      useLocal(typeVariable.element);
+      // Field initializers are inlined and access the type variable as
+      // normal parameters.
+      if (!outermostElement.isField()) {
+        registerNeedsThis();
       }
-      return false;
-    }
+    });
+  }
 
-    void analyzeTypeVariables(DartType type) {
-      if (type is TypeVariableType) {
-        useLocal(type.element);
-      } else if (type is InterfaceType) {
-        InterfaceType ifcType = type;
-        for (DartType argument in ifcType.typeArguments) {
-          analyzeTypeVariables(argument);
-        }
-      }
-    }
-
+  void analyzeType(DartType type) {
+    // TODO(johnniwinther): Find out why this can be null.
+    if (type == null) return;
     if (outermostElement.isMember() &&
-        compiler.backend.needsRti(outermostElement.getEnclosingClass())) {
-      if (outermostElement.isConstructor() || outermostElement.isField()) {
+        compiler.backend.classNeedsRti(outermostElement.getEnclosingClass())) {
+      if (outermostElement.isConstructor() ||
+          outermostElement.isField()) {
         analyzeTypeVariables(type);
       } else if (outermostElement.isInstanceMember()) {
-        if (hasTypeVariable(type)) {
+        if (type.containsTypeVariables) {
           registerNeedsThis();
         }
       }
     }
-
-    node.visitChildren(this);
   }
 
   // If variables that are declared in the [node] scope are captured and need
@@ -737,7 +740,7 @@
       }
 
       if (currentElement.isFactoryConstructor() &&
-          compiler.backend.needsRti(currentElement.enclosingElement)) {
+          compiler.backend.classNeedsRti(currentElement.enclosingElement)) {
         // Declare the type parameters in the scope. Generative
         // constructors just use 'this'.
         ClassElement cls = currentElement.enclosingElement;
@@ -746,9 +749,18 @@
         });
       }
 
+      DartType type = element.computeType(compiler);
       // Compute the function type and check for type variables in return or
       // parameter types.
-      if (element.computeType(compiler).containsTypeVariables) {
+      if (type.containsTypeVariables) {
+        registerNeedsThis();
+      }
+      // Ensure that closure that need runtime type information has access to
+      // this of the enclosing class.
+      if (element is FunctionElement &&
+          closureData.thisElement != null &&
+          type.containsTypeVariables &&
+          compiler.backend.methodNeedsRti(element)) {
         registerNeedsThis();
       }
 
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index ecc86458..d51b1b2 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -32,6 +32,9 @@
   /** Caches the createRuntimeType function if registered. */
   Element createRuntimeTypeFunction = null;
 
+  /** Caches the setRuntimeTypeInfo function if registered. */
+  Element setRuntimeTypeInfoFunction = null;
+
   ConstantHandler(Compiler compiler, this.constantSystem,
                   { bool this.isMetadata: false })
       : initialVariableValues = new Map<VariableElement, dynamic>(),
@@ -43,37 +46,58 @@
   String get name => 'ConstantHandler';
 
   void registerCompileTimeConstant(Constant constant, TreeElements elements) {
-    registerInstantiatedClass(constant.computeType(compiler).element, elements);
+    registerInstantiatedType(constant.computeType(compiler), elements);
     if (constant.isFunction()) {
       FunctionConstant function = constant;
       registerGetOfStaticFunction(function.element);
     } else if (constant.isInterceptor()) {
       // An interceptor constant references the class's prototype chain.
       InterceptorConstant interceptor = constant;
-      registerInstantiatedClass(interceptor.dispatchedType.element, elements);
+      registerInstantiatedType(interceptor.dispatchedType, elements);
     }
     compiledConstants.add(constant);
   }
 
-  void registerInstantiatedClass(ClassElement element, TreeElements elements) {
-    if (isMetadata) return;
-    compiler.enqueuer.codegen.registerInstantiatedClass(element, elements);
+  void registerInstantiatedType(DartType type, TreeElements elements) {
+    if (isMetadata) {
+      compiler.backend.registerMetadataInstantiatedType(type, elements);
+      return;
+    }
+    compiler.enqueuer.codegen.registerInstantiatedType(type, elements);
+    if (type is InterfaceType &&
+        !type.isRaw &&
+        compiler.backend.classNeedsRti(type.element)) {
+      registerSetRuntimeTypeInfoFunction();
+    }
   }
 
   void registerStaticUse(Element element) {
-    if (isMetadata) return;
+    if (isMetadata) {
+      compiler.backend.registerMetadataStaticUse(element);
+      return;
+    }
     compiler.analyzeElement(element.declaration);
     compiler.enqueuer.codegen.registerStaticUse(element);
   }
 
   void registerGetOfStaticFunction(FunctionElement element) {
-    if (isMetadata) return;
+    if (isMetadata) {
+      compiler.backend.registerMetadataGetOfStaticFunction(element);
+      return;
+    }
     compiler.analyzeElement(element.declaration);
     compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
   }
 
   void registerStringInstance(TreeElements elements) {
-    registerInstantiatedClass(compiler.stringClass, elements);
+    registerInstantiatedType(compiler.stringClass.rawType, elements);
+  }
+
+  void registerSetRuntimeTypeInfoFunction() {
+    if (setRuntimeTypeInfoFunction != null) return;
+    SourceString helperName = const SourceString('setRuntimeTypeInfo');
+    setRuntimeTypeInfoFunction = compiler.findHelper(helperName);
+    registerStaticUse(setRuntimeTypeInfoFunction);
   }
 
   void registerCreateRuntimeTypeFunction() {
@@ -318,17 +342,17 @@
   }
 
   Constant visitLiteralBool(LiteralBool node) {
-    handler.registerInstantiatedClass(compiler.boolClass, elements);
+    handler.registerInstantiatedType(compiler.boolClass.rawType, elements);
     return constantSystem.createBool(node.value);
   }
 
   Constant visitLiteralDouble(LiteralDouble node) {
-    handler.registerInstantiatedClass(compiler.doubleClass, elements);
+    handler.registerInstantiatedType(compiler.doubleClass.rawType, elements);
     return constantSystem.createDouble(node.value);
   }
 
   Constant visitLiteralInt(LiteralInt node) {
-    handler.registerInstantiatedClass(compiler.intClass, elements);
+    handler.registerInstantiatedType(compiler.intClass.rawType, elements);
     return constantSystem.createInt(node.value);
   }
 
@@ -342,9 +366,8 @@
          link = link.tail) {
       arguments.add(evaluateConstant(link.head));
     }
-    // TODO(9476): get type parameters.
-    compiler.listClass.computeType(compiler);
-    DartType type = compiler.listClass.rawType;
+    DartType type = elements.getType(node);
+    handler.registerInstantiatedType(type, elements);
     Constant constant = new ListConstant(type, arguments);
     handler.registerCompileTimeConstant(constant, elements);
     return constant;
@@ -379,9 +402,10 @@
       }
     }
     bool hasProtoKey = (protoValue != null);
-    // TODO(9476): this should be a List<String> type.
-    compiler.listClass.computeType(compiler);
-    DartType keysType = compiler.listClass.rawType;
+    InterfaceType sourceType = elements.getType(node);
+    Link<DartType> arguments =
+        new Link<DartType>.fromList([compiler.stringClass.rawType]);
+    DartType keysType = new InterfaceType(compiler.listClass, arguments);
     ListConstant keysList = new ListConstant(keysType, keys);
     handler.registerCompileTimeConstant(keysList, elements);
     SourceString className = hasProtoKey
@@ -389,9 +413,9 @@
                              : MapConstant.DART_CLASS;
     ClassElement classElement = compiler.jsHelperLibrary.find(className);
     classElement.ensureResolved(compiler);
-    // TODO(9476): copy over the generic type.
-    DartType type = classElement.rawType;
-    handler.registerInstantiatedClass(classElement, elements);
+    Link<DartType> typeArgument = sourceType.typeArguments.tail;
+    InterfaceType type = new InterfaceType(classElement, typeArgument);
+    handler.registerInstantiatedType(type, elements);
     Constant constant = new MapConstant(type, keysList, values, protoValue);
     handler.registerCompileTimeConstant(constant, elements);
     return constant;
@@ -444,9 +468,7 @@
 
   Constant makeTypeConstant(Element element) {
     DartType elementType = element.computeType(compiler).asRaw();
-    if (compiler.mirrorsEnabled) {
-      handler.registerInstantiatedClass(element, elements);
-    }
+    compiler.backend.registerTypeLiteral(element, elements);
     DartType constantType =
         compiler.backend.typeImplementation.computeType(compiler);
     Constant constant = new TypeConstant(elementType, constantType);
@@ -654,6 +676,12 @@
     // constructor to ensure the redirectionTarget has been computed
     // correctly.  Find a way to avoid this.
     compiler.analyzeElement(constructor.declaration);
+
+    InterfaceType type = elements.getType(node);
+    if ( constructor.isRedirectingFactory) {
+      type = constructor.computeTargetType(compiler, type);
+    }
+
     constructor = constructor.redirectionTarget;
     ClassElement classElement = constructor.getEnclosingClass();
     // The constructor must be an implementation to ensure that field
@@ -669,10 +697,7 @@
     evaluator.evaluateConstructorFieldValues(arguments);
     List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
 
-    handler.registerInstantiatedClass(classElement, elements);
-    // TODO(9476): take generic types into account.
-    classElement.computeType(compiler);
-    DartType type = classElement.rawType;
+    handler.registerInstantiatedType(type, elements);
     Constant constant = new ConstructedConstant(type, jsNewArguments);
     handler.registerCompileTimeConstant(constant, elements);
     return constant;
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 75844c2..a5ac2e0 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -126,7 +126,8 @@
     return new ItemCompilationContext();
   }
 
-  bool needsRti(ClassElement cls);
+  bool classNeedsRti(ClassElement cls);
+  bool methodNeedsRti(FunctionElement function);
 
   // The following methods are hooks for the backend to register its
   // helper methods.
@@ -140,7 +141,7 @@
   void registerThrowExpression(TreeElements elements) {}
   void registerLazyField(TreeElements elements) {}
   void registerTypeVariableExpression(TreeElements elements) {}
-  void registerTypeLiteral(TreeElements elements) {}
+  void registerTypeLiteral(Element element, TreeElements elements) {}
   void registerStackTraceInCatch(TreeElements elements) {}
   void registerIsCheck(DartType type,
                        Enqueuer enqueuer,
@@ -152,11 +153,31 @@
   void registerFallThroughError(TreeElements elements) {}
   void registerSuperNoSuchMethod(TreeElements elements) {}
   void registerConstantMap(TreeElements elements) {}
-  void registerRuntimeType(TreeElements elements) {}
+  /**
+   * Call this to register that an instantiated generic class has a call
+   * method.
+   */
+  void registerGenericCallMethod(Element callMethod,
+                                 Enqueuer enqueuer,
+                                 TreeElements elements) {}
+  /**
+   * Call this to register that a getter exists for a function on an
+   * instantiated generic class.
+   */
+  void registerGenericClosure(Element closure,
+                              Enqueuer enqueuer,
+                              TreeElements elements) {}
+  /**
+   * Call this to register that the [:runtimeType:] property has been accessed.
+   */
+  void registerRuntimeType(Enqueuer enqueuer, TreeElements elements) {}
 
   void registerRequiredType(DartType type, Element enclosingElement) {}
   void registerClassUsingVariableExpression(ClassElement cls) {}
 
+  void registerConstSymbol(String name, TreeElements elements) {}
+  void registerNewSymbol(TreeElements elements) {}
+
   bool isNullImplementation(ClassElement cls) {
     return cls == compiler.nullClass;
   }
@@ -183,9 +204,13 @@
     return classElement == compiler.objectClass;
   }
 
-  void enableMirrors() {}
-
   void registerStaticUse(Element element, Enqueuer enqueuer) {}
+
+  void onLibraryScanned(LibraryElement library, Uri uri) {}
+
+  void registerMetadataInstantiatedType(DartType type, TreeElements elements) {}
+  void registerMetadataStaticUse(Element element) {}
+  void registerMetadataGetOfStaticFunction(FunctionElement element) {}
 }
 
 /**
@@ -529,8 +554,6 @@
 
   bool get hasBuildId => buildId != UNDETERMINED_BUILD_ID;
 
-  bool get mirrorsEnabled => mirrorSystemClass != null;
-
   bool get analyzeAll => analyzeAllFlag || compileAll;
 
   bool get compileAll => false;
@@ -674,11 +697,10 @@
     }
     if (uri == Uri.parse('dart:mirrors')) {
       mirrorSystemClass = library.find(const SourceString('MirrorSystem'));
-      backend.enableMirrors();
-      metadataHandler = constantHandler;
     } else if (uri == Uri.parse('dart:_collection-dev')) {
       symbolImplementationClass = library.find(const SourceString('Symbol'));
     }
+    backend.onLibraryScanned(library, uri);
   }
 
   void onClassResolved(ClassElement cls) {
@@ -760,6 +782,15 @@
         listClass.lookupConstructor(callConstructor);
   }
 
+  Element _filledListConstructor;
+  Element get filledListConstructor {
+    if (_filledListConstructor != null) return _filledListConstructor;
+    Selector callConstructor = new Selector.callConstructor(
+        const SourceString("filled"), listClass.getLibrary());
+    return _filledListConstructor =
+        listClass.lookupConstructor(callConstructor);
+  }
+
   void scanBuiltinLibraries() {
     jsHelperLibrary = scanBuiltinLibrary('_js_helper');
     interceptorsLibrary = scanBuiltinLibrary('_interceptors');
@@ -857,7 +888,6 @@
     // Elements required by enqueueHelpers are global dependencies
     // that are not pulled in by a particular element.
     backend.enqueueHelpers(enqueuer.resolution, globalDependencies);
-    resolveReflectiveDataIfNeeded();
     processQueue(enqueuer.resolution, main);
     enqueuer.resolution.logSummary(log);
 
@@ -887,7 +917,7 @@
       enqueuer.codegen.registerGetOfStaticFunction(mainApp.find(MAIN));
     }
     if (enabledNoSuchMethod) {
-      enqueuer.codegen.registerInvocation(NO_SUCH_METHOD, noSuchMethodSelector);
+      enqueuer.codegen.registerInvocation(noSuchMethodSelector);
       enqueuer.codegen.addToWorkList(createInvocationMirrorElement);
     }
     if (compileAll) {
@@ -903,17 +933,6 @@
     checkQueues();
   }
 
-  void resolveReflectiveDataIfNeeded() {
-    // Only need reflective data when dart:mirrors is loaded.
-    if (!mirrorsEnabled) return;
-
-    for (LibraryElement library in libraries.values) {
-      for (Link link = library.metadata; !link.isEmpty; link = link.tail) {
-        link.head.ensureResolved(this);
-      }
-    }
-  }
-
   void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) {
     void enqueueAll(Element element) {
       fullyEnqueueTopLevelElement(element, world);
@@ -1128,6 +1147,12 @@
                   api.Diagnostic.INFO);
   }
 
+  void reportInternalError(Spannable node, String message) {
+    reportMessage(spanFromSpannable(node),
+                  MessageKind.GENERIC.error({'text': message}),
+                  api.Diagnostic.ERROR);
+  }
+
   void reportMessage(SourceSpan span, Diagnostic message, api.Diagnostic kind) {
     // TODO(ahe): The names Diagnostic and api.Diagnostic are in
     // conflict. Fix it.
diff --git a/sdk/lib/_internal/compiler/implementation/constants.dart b/sdk/lib/_internal/compiler/implementation/constants.dart
index eae62ead..06e04fc 100644
--- a/sdk/lib/_internal/compiler/implementation/constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/constants.dart
@@ -346,14 +346,17 @@
 
   ListConstant(DartType type, List<Constant> entries)
       : this.entries = entries,
-        hashCode = _computeHash(entries),
+        hashCode = _computeHash(type, entries),
         super(type);
   bool isList() => true;
 
-  static int _computeHash(List<Constant> entries) {
+  static int _computeHash(DartType type, List<Constant> entries) {
     // TODO(floitsch): create a better hash.
-    int hash = 0;
-    for (Constant input in entries) hash ^= input.hashCode;
+    int hash = 7;
+    for (Constant input in entries) {
+      hash ^= input.hashCode;
+    }
+    hash ^= type.hashCode;
     return hash;
   }
 
@@ -361,7 +364,7 @@
     if (other is !ListConstant) return false;
     ListConstant otherList = other;
     if (hashCode != otherList.hashCode) return false;
-    // TODO(floitsch): verify that the generic types are the same.
+    if (type != otherList.type) return false;
     if (entries.length != otherList.entries.length) return false;
     for (int i = 0; i < entries.length; i++) {
       if (entries[i] != otherList.entries[i]) return false;
@@ -400,14 +403,17 @@
 
   MapConstant(DartType type, this.keys, List<Constant> values, this.protoValue)
       : this.values = values,
-        this.hashCode = computeHash(values),
+        this.hashCode = computeHash(type, values),
         super(type);
   bool isMap() => true;
 
-  static int computeHash(List<Constant> values) {
+  static int computeHash(DartType type, List<Constant> values) {
     // TODO(floitsch): create a better hash.
     int hash = 0;
-    for (Constant value in values) hash ^= value.hashCode;
+    for (Constant value in values) {
+      hash ^= value.hashCode;
+    }
+    hash ^= type.hashCode;
     return hash;
   }
 
@@ -415,7 +421,7 @@
     if (other is !MapConstant) return false;
     MapConstant otherMap = other;
     if (hashCode != otherMap.hashCode) return false;
-    // TODO(floitsch): verify that the generic types are the same.
+    if (type != other.type) return false;
     if (keys != otherMap.keys) return false;
     for (int i = 0; i < values.length; i++) {
       if (values[i] != otherMap.values[i]) return false;
@@ -475,7 +481,7 @@
     for (Constant field in fields) {
       hash ^= field.hashCode;
     }
-    hash ^= type.element.hashCode;
+    hash ^= type.hashCode;
     return hash;
   }
 
@@ -483,8 +489,7 @@
     if (otherVar is !ConstructedConstant) return false;
     ConstructedConstant other = otherVar;
     if (hashCode != other.hashCode) return false;
-    // TODO(floitsch): verify that the (generic) types are the same.
-    if (type.element != other.type.element) return false;
+    if (type != other.type) return false;
     if (fields.length != other.fields.length) return false;
     for (int i = 0; i < fields.length; i++) {
       if (fields[i] != other.fields[i]) return false;
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
index 609b2be..358ecab 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -221,7 +221,8 @@
         stripAsserts = strips.indexOf('asserts') != -1,
         super(compiler);
 
-  bool needsRti(ClassElement cls) => false;
+  bool classNeedsRti(ClassElement cls) => false;
+  bool methodNeedsRti(FunctionElement function) => false;
 
   void enqueueHelpers(ResolutionEnqueuer world, TreeElements elements) {
     // Right now resolver doesn't always resolve interfaces needed
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index bcec921..d4fc525 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -908,6 +908,8 @@
 }
 
 abstract class DartTypeVisitor<R, A> {
+  const DartTypeVisitor();
+
   R visitType(DartType type, A argument);
 
   R visitVoidType(VoidType type, A argument) =>
@@ -938,6 +940,9 @@
       visitInterfaceType(type, argument);
 }
 
+/**
+ * Type visitor that determines the subtype relation two types.
+ */
 class SubtypeVisitor extends DartTypeVisitor<bool, DartType> {
   final Compiler compiler;
   final DynamicType dynamicType;
@@ -1140,6 +1145,7 @@
   final VoidType voidType;
   final DynamicType dynamicType;
   final SubtypeVisitor subtypeVisitor;
+  final PotentialSubtypeVisitor potentialSubtypeVisitor;
 
   factory Types(Compiler compiler, BaseClassElementX dynamicElement) {
     LibraryElement library = new LibraryElementX(new Script(null, null));
@@ -1148,11 +1154,15 @@
     dynamicElement.rawTypeCache = dynamicElement.thisType = dynamicType;
     SubtypeVisitor subtypeVisitor =
         new SubtypeVisitor(compiler, dynamicType, voidType);
-    return new Types.internal(compiler, voidType, dynamicType, subtypeVisitor);
+    PotentialSubtypeVisitor potentialSubtypeVisitor =
+        new PotentialSubtypeVisitor(compiler, dynamicType, voidType);
+
+    return new Types.internal(compiler, voidType, dynamicType,
+        subtypeVisitor, potentialSubtypeVisitor);
   }
 
   Types.internal(this.compiler, this.voidType, this.dynamicType,
-                 this.subtypeVisitor);
+                 this.subtypeVisitor, this.potentialSubtypeVisitor);
 
   /** Returns true if t is a subtype of s */
   bool isSubtype(DartType t, DartType s) {
@@ -1163,6 +1173,11 @@
     return subtypeVisitor.isAssignable(r, s);
   }
 
+  bool isPotentialSubtype(DartType t, DartType s) {
+    // TODO(johnniwinther): Return a set of variable points in the positive
+    // cases.
+    return potentialSubtypeVisitor.isSubtype(t, s);
+  }
 
   /**
    * Helper method for performing substitution of a linked list of types.
@@ -1217,3 +1232,23 @@
     return typeVariable.element.enclosingElement;
   }
 }
+
+/**
+ * Type visitor that determines one type could a subtype of another given the
+ * right type variable substitution. The computation is approximate and returns
+ * [:false:] only if we are sure no such substitution exists.
+ */
+class PotentialSubtypeVisitor extends SubtypeVisitor {
+  PotentialSubtypeVisitor(Compiler compiler,
+                          DynamicType dynamicType,
+                          VoidType voidType)
+      : super(compiler, dynamicType, voidType);
+
+
+  bool isSubtype(DartType t, DartType s) {
+    if (t is TypeVariableType || s is TypeVariableType) {
+      return true;
+    }
+    return super.isSubtype(t, s);
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index ea72505..2bd5812 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -526,6 +526,16 @@
         && node.arguments.isEmpty;
   }
 
+  static bool isFilledListConstructorCall(Element element,
+                                          Send node,
+                                          Compiler compiler) {
+    return element == compiler.filledListConstructor
+        && node.isCall
+        && !node.arguments.isEmpty
+        && !node.arguments.tail.isEmpty
+        && node.arguments.tail.tail.isEmpty;
+  }
+
   static bool switchStatementHasContinue(SwitchStatement node,
                                          TreeElements elements) {
     for (SwitchCase switchCase in node.cases) {
@@ -739,6 +749,16 @@
 
   bool get isRedirectingFactory;
 
+  /**
+   * Compute the type of the target of a redirecting constructor or factory
+   * for an instantiation site with type [:newType:].
+   *
+   * TODO(karlklose): get rid of this method and resolve the target type
+   * during resolution when we correctly resolve chains of redirections.
+   */
+  InterfaceType computeTargetType(Compiler compiler,
+                                  InterfaceType newType);
+
   // TODO(kasperl): These are bit fishy. Do we really need them?
   void set patch(FunctionElement value);
   void set origin(FunctionElement value);
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 66f97f4..3d90f47 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -1253,6 +1253,19 @@
     return target;
   }
 
+  InterfaceType computeTargetType(Compiler compiler,
+                                  InterfaceType newType) {
+    if (!isRedirectingFactory) return newType;
+    ClassElement targetClass = getEnclosingClass();
+    TreeElements treeElements =
+        compiler.enqueuer.resolution.getCachedElements(
+            declaration);
+    FunctionExpression functionNode = parseNode(compiler);
+    Return redirectionNode = functionNode.body;
+    return treeElements.getType(redirectionNode.expression)
+        .subst(newType.typeArguments, targetClass.typeVariables);
+  }
+
   /**
    * Applies a patch function to this function. The patch function's body
    * is used as replacement when parsing this function's body.
diff --git a/sdk/lib/_internal/compiler/implementation/enqueue.dart b/sdk/lib/_internal/compiler/implementation/enqueue.dart
index 1352cea..80ed094 100644
--- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
+++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
@@ -152,11 +152,7 @@
 
   void registerTypeLiteral(Element element, TreeElements elements) {
     registerInstantiatedClass(compiler.typeClass, elements);
-    compiler.backend.registerTypeLiteral(elements);
-    if (compiler.mirrorsEnabled) {
-      // In order to use reflectClass, we need to find the constructor.
-      registerInstantiatedClass(element, elements);
-    }
+    compiler.backend.registerTypeLiteral(element, elements);
   }
 
   bool checkNoEnqueuedInvokedInstanceMethods() {
@@ -177,9 +173,6 @@
     cls.implementation.forEachMember(processInstantiatedClassMember);
   }
 
-  /**
-   * Documentation wanted -- johnniwinther
-   */
   void processInstantiatedClassMember(ClassElement cls, Element member) {
     assert(invariant(member, member.isDeclaration));
     if (isProcessed(member)) return;
@@ -232,14 +225,14 @@
       if (member.name == Compiler.NO_SUCH_METHOD) {
         enableNoSuchMethod(member);
       }
+      if (member.name == Compiler.CALL_OPERATOR_NAME &&
+          !cls.typeVariables.isEmpty) {
+        registerGenericCallMethod(member, compiler.globalDependencies);
+      }
       // If there is a property access with the same name as a method we
       // need to emit the method.
       if (universe.hasInvokedGetter(member, compiler)) {
-        // We will emit a closure, so make sure the bound closure class is
-        // generated.
-        registerInstantiatedClass(compiler.boundClosureClass,
-                                  // Precise dependency is not important here.
-                                  compiler.globalDependencies);
+        registerClosurizedMember(member, compiler.globalDependencies);
         return addToWorkList(member);
       }
       // Store the member in [instanceFunctionsByName] to catch
@@ -298,13 +291,9 @@
     });
   }
 
-  void registerNewSelector(SourceString name,
-                           Selector selector,
+  void registerNewSelector(Selector selector,
                            Map<SourceString, Set<Selector>> selectorsMap) {
-    if (name != selector.name) {
-      String message = "$name != ${selector.name} (${selector.kind})";
-      compiler.internalError("Wrong selector name: $message.");
-    }
+    SourceString name = selector.name;
     Set<Selector> selectors =
         selectorsMap.putIfAbsent(name, () => new Set<Selector>());
     if (!selectors.contains(selector)) {
@@ -313,38 +302,27 @@
     }
   }
 
-  void registerInvocation(SourceString methodName, Selector selector) {
+  void registerInvocation(Selector selector) {
     task.measure(() {
-      registerNewSelector(methodName, selector, universe.invokedNames);
+      registerNewSelector(selector, universe.invokedNames);
     });
   }
 
-  void registerInvokedGetter(SourceString getterName, Selector selector) {
+  void registerInvokedGetter(Selector selector) {
     task.measure(() {
-      registerNewSelector(getterName, selector, universe.invokedGetters);
+      registerNewSelector(selector, universe.invokedGetters);
     });
   }
 
-  void registerInvokedSetter(SourceString setterName, Selector selector) {
+  void registerInvokedSetter(Selector selector) {
     task.measure(() {
-      registerNewSelector(setterName, selector, universe.invokedSetters);
+      registerNewSelector(selector, universe.invokedSetters);
     });
   }
 
   /// Called when [:const Symbol(name):] is seen.
   void registerConstSymbol(String name, TreeElements elements) {
-    // If dart:mirrors is loaded, a const symbol may be used to call a
-    // static/top-level method or accessor, instantiate a class, call
-    // an instance method or accessor with the given name.
-    if (!compiler.mirrorsEnabled) return;
-
-    task.ensureAllElementsByName();
-
-    for (var link = task.allElementsByName[name];
-         link != null && !link.isEmpty;
-         link = link.tail) {
-      pretendElementWasUsed(link.head, elements);
-    }
+    compiler.backend.registerConstSymbol(name, elements);
   }
 
   void pretendElementWasUsed(Element element, TreeElements elements) {
@@ -367,27 +345,28 @@
             element.asFunctionElement().requiredParameterCount(compiler);
         Selector selector =
             new Selector.call(element.name, element.getLibrary(), arity);
-        registerInvocation(element.name, selector);
+        registerInvocation(selector);
       } else if (element.isSetter()) {
         Selector selector =
             new Selector.setter(element.name, element.getLibrary());
-        registerInvokedSetter(element.name, selector);
+        registerInvokedSetter(selector);
       } else if (element.isGetter()) {
         Selector selector =
             new Selector.getter(element.name, element.getLibrary());
-        registerInvokedGetter(element.name, selector);
+        registerInvokedGetter(selector);
       } else if (element.isField()) {
         Selector selector =
             new Selector.setter(element.name, element.getLibrary());
-        registerInvokedSetter(element.name, selector);
+        registerInvokedSetter(selector);
         selector = new Selector.getter(element.name, element.getLibrary());
-        registerInvokedGetter(element.name, selector);
+        registerInvokedGetter(selector);
       }
     }
   }
 
   /// Called when [:new Symbol(...):] is seen.
   void registerNewSymbol(TreeElements elements) {
+    compiler.backend.registerNewSymbol(elements);
   }
 
   void enqueueEverything() {
@@ -408,11 +387,15 @@
     String memberName = n.slowToString();
     Link<Element> members = map[memberName];
     if (members != null) {
+      // [f] might add elements to [: map[memberName] :] during the loop below
+      // so we create a new list for [: map[memberName] :] and prepend the
+      // [remaining] members after the loop.
+      map[memberName] = const Link<Element>();
       LinkBuilder<Element> remaining = new LinkBuilder<Element>();
       for (; !members.isEmpty; members = members.tail) {
         if (!f(members.head)) remaining.addLast(members.head);
       }
-      map[memberName] = remaining.toLink();
+      map[memberName] = remaining.toLink(map[memberName]);
     }
   }
 
@@ -427,6 +410,9 @@
   void handleUnseenSelector(SourceString methodName, Selector selector) {
     processInstanceMembers(methodName, (Element member) {
       if (selector.appliesUnnamed(member, compiler)) {
+        if (member.isFunction() && selector.isGetter()) {
+          registerClosurizedMember(member, compiler.globalDependencies);
+        }
         if (member.isField() && member.getEnclosingClass().isNative()) {
           if (selector.isGetter() || selector.isCall()) {
             nativeEnqueuer.registerFieldLoad(member);
@@ -453,11 +439,7 @@
     if (selector.isGetter()) {
       processInstanceFunctions(methodName, (Element member) {
         if (selector.appliesUnnamed(member, compiler)) {
-          // We will emit a closure, so make sure the bound closure class is
-          // generated.
-          registerInstantiatedClass(compiler.boundClosureClass,
-                                    // Precise dependency is not important here.
-                                    compiler.globalDependencies);
+          registerBoundClosure();
           return true;
         }
         return false;
@@ -484,49 +466,27 @@
     universe.staticFunctionsNeedingGetter.add(element);
   }
 
-  void registerDynamicInvocation(SourceString methodName, Selector selector) {
+  void registerDynamicInvocation(Selector selector) {
     assert(selector != null);
-    registerInvocation(methodName, selector);
-  }
-
-  void registerDynamicInvocationOf(Element element, Selector selector) {
-    assert(selector.isCall()
-           || selector.isOperator()
-           || selector.isIndex()
-           || selector.isIndexSet());
-    if (element.isFunction() || element.isGetter()) {
-      addToWorkList(element);
-    } else if (element.isAbstractField()) {
-      AbstractFieldElement field = element;
-      // Since the invocation is a dynamic call on a getter, we only
-      // need to schedule the getter on the work list.
-      addToWorkList(field.getter);
-    } else {
-      assert(element.isField());
-    }
-    // We also need to add the selector to the invoked names map,
-    // because the emitter uses that map to generate parameter stubs.
-    Set<Selector> selectors = universe.invokedNames.putIfAbsent(
-        element.name, () => new Set<Selector>());
-    selectors.add(selector);
+    registerInvocation(selector);
   }
 
   void registerSelectorUse(Selector selector) {
     if (selector.isGetter()) {
-      registerInvokedGetter(selector.name, selector);
+      registerInvokedGetter(selector);
     } else if (selector.isSetter()) {
-      registerInvokedSetter(selector.name, selector);
+      registerInvokedSetter(selector);
     } else {
-      registerInvocation(selector.name, selector);
+      registerInvocation(selector);
     }
   }
 
-  void registerDynamicGetter(SourceString methodName, Selector selector) {
-    registerInvokedGetter(methodName, selector);
+  void registerDynamicGetter(Selector selector) {
+    registerInvokedGetter(selector);
   }
 
-  void registerDynamicSetter(SourceString methodName, Selector selector) {
-    registerInvokedSetter(methodName, selector);
+  void registerDynamicSetter(Selector selector) {
+    registerInvokedSetter(selector);
   }
 
   void registerFieldGetter(Element element) {
@@ -538,12 +498,12 @@
   }
 
   void registerIsCheck(DartType type, TreeElements elements) {
+    type = universe.registerIsCheck(type, compiler);
     // Even in checked mode, type annotations for return type and argument
     // types do not imply type checks, so there should never be a check
     // against the type variable of a typedef.
     assert(type.kind != TypeKind.TYPE_VARIABLE ||
            !type.element.enclosingElement.isTypedef());
-    universe.isChecks.add(type);
     compiler.backend.registerIsCheck(type, this, elements);
   }
 
@@ -561,6 +521,32 @@
     compiler.backend.registerAsCheck(type, elements);
   }
 
+  void registerGenericCallMethod(Element element, TreeElements elements) {
+    compiler.backend.registerGenericCallMethod(element, this, elements);
+    universe.genericCallMethods.add(element);
+  }
+
+  void registerBoundClosure() {
+    registerInstantiatedClass(compiler.boundClosureClass,
+                              // Precise dependency is not important here.
+                              compiler.globalDependencies);
+  }
+
+  void registerClosurizedMember(Element element, TreeElements elements) {
+    if (element.computeType(compiler).containsTypeVariables) {
+      registerClosurizedGenericMember(element, elements);
+    } else {
+      registerBoundClosure();
+    }
+    universe.closurizedMembers.add(element);
+  }
+
+  void registerClosurizedGenericMember(Element element, TreeElements elements) {
+    registerBoundClosure();
+    compiler.backend.registerGenericClosure(element, this, elements);
+    universe.closurizedGenericMembers.add(element);
+  }
+
   void forEach(f(WorkItem work));
 
   void forEachPostProcessTask(f(PostProcessTask work)) {}
@@ -655,7 +641,7 @@
       // runtime type.
       compiler.enabledRuntimeType = true;
       // TODO(ahe): Record precise dependency here.
-      compiler.backend.registerRuntimeType(compiler.globalDependencies);
+      compiler.backend.registerRuntimeType(this, compiler.globalDependencies);
     } else if (element == compiler.functionApplyMethod) {
       compiler.enabledFunctionApply = true;
     } else if (element == compiler.invokeOnMethod) {
@@ -683,7 +669,7 @@
 
     Selector selector = compiler.noSuchMethodSelector;
     compiler.enabledNoSuchMethod = true;
-    registerInvocation(Compiler.NO_SUCH_METHOD, selector);
+    registerInvocation(selector);
 
     compiler.createInvocationMirrorElement =
         compiler.findHelper(Compiler.CREATE_INVOCATION_MIRROR);
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 5afa2a0..46abf0a 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -11,6 +11,118 @@
       : boundsChecked = new Set<HInstruction>();
 }
 
+class CheckedModeHelper {
+  final SourceString name;
+
+  const CheckedModeHelper(SourceString this.name);
+
+  Element getElement(Compiler compiler) => compiler.findHelper(name);
+
+  jsAst.Expression generateCall(SsaCodeGenerator codegen,
+                                HTypeConversion node) {
+    Element helperElement = getElement(codegen.compiler);
+    codegen.world.registerStaticUse(helperElement);
+    List<jsAst.Expression> arguments = <jsAst.Expression>[];
+    codegen.use(node.checkedInput);
+    arguments.add(codegen.pop());
+    generateAdditionalArguments(codegen, node, arguments);
+    String helperName = codegen.backend.namer.isolateAccess(helperElement);
+    return new jsAst.Call(new jsAst.VariableUse(helperName), arguments);
+  }
+
+  void generateAdditionalArguments(SsaCodeGenerator codegen,
+                                   HTypeConversion node,
+                                   List<jsAst.Expression> arguments) {
+    assert(!node.typeExpression.isMalformed);
+    // No additional arguments needed.
+  }
+}
+
+class PropertyCheckedModeHelper extends CheckedModeHelper {
+  const PropertyCheckedModeHelper(SourceString name) : super(name);
+
+  void generateAdditionalArguments(SsaCodeGenerator codegen,
+                                   HTypeConversion node,
+                                   List<jsAst.Expression> arguments) {
+    DartType type = node.typeExpression;
+    assert(!type.isMalformed);
+    String additionalArgument = codegen.backend.namer.operatorIsType(type);
+    arguments.add(js.string(additionalArgument));
+  }
+}
+
+class TypeVariableCheckedModeHelper extends CheckedModeHelper {
+  const TypeVariableCheckedModeHelper(SourceString name) : super(name);
+
+  void generateAdditionalArguments(SsaCodeGenerator codegen,
+                                   HTypeConversion node,
+                                   List<jsAst.Expression> arguments) {
+    assert(node.typeExpression.kind == TypeKind.TYPE_VARIABLE);
+    codegen.use(node.typeRepresentation);
+    arguments.add(codegen.pop());
+  }
+}
+
+class SubtypeCheckedModeHelper extends CheckedModeHelper {
+  const SubtypeCheckedModeHelper(SourceString name) : super(name);
+
+  void generateAdditionalArguments(SsaCodeGenerator codegen,
+                                   HTypeConversion node,
+                                   List<jsAst.Expression> arguments) {
+    DartType type = node.typeExpression;
+    Element element = type.element;
+    String isField = codegen.backend.namer.operatorIs(element);
+    arguments.add(js.string(isField));
+    codegen.use(node.typeRepresentation);
+    arguments.add(codegen.pop());
+    String asField = codegen.backend.namer.substitutionName(element);
+    arguments.add(js.string(asField));
+  }
+}
+
+class FunctionTypeCheckedModeHelper extends CheckedModeHelper {
+  const FunctionTypeCheckedModeHelper(SourceString name) : super(name);
+
+  void generateAdditionalArguments(SsaCodeGenerator codegen,
+                                   HTypeConversion node,
+                                   List<jsAst.Expression> arguments) {
+    DartType type = node.typeExpression;
+    String signatureName = codegen.backend.namer.getFunctionTypeName(type);
+    arguments.add(js.string(signatureName));
+
+    if (type.containsTypeVariables) {
+      ClassElement contextClass = Types.getClassContext(type);
+      String contextName = codegen.backend.namer.getName(contextClass);
+      arguments.add(js.string(contextName));
+
+      if (node.contextIsTypeArguments) {
+        arguments.add(new jsAst.LiteralNull());
+        codegen.use(node.context);
+        arguments.add(codegen.pop());
+      } else {
+        codegen.use(node.context);
+        arguments.add(codegen.pop());
+      }
+    }
+  }
+}
+
+class MalformedCheckedModeHelper extends CheckedModeHelper {
+  const MalformedCheckedModeHelper(SourceString name) : super(name);
+
+  void generateAdditionalArguments(SsaCodeGenerator codegen,
+                                   HTypeConversion node,
+                                   List<jsAst.Expression> arguments) {
+    DartType type = node.typeExpression;
+    assert(type.isMalformed);
+    String reasons = Types.fetchReasonsFromMalformedType(type);
+    arguments.add(js.string('$type'));
+    // TODO(johnniwinther): Handle escaping correctly.
+    arguments.add(js.string(reasons));
+  }
+}
+
+
 class JavaScriptBackend extends Backend {
   SsaBuilderTask builder;
   SsaOptimizerTask optimizer;
@@ -98,13 +210,6 @@
   ClassElement jsIndexingBehaviorInterface;
 
   /**
-   * A collection of selectors of intercepted method calls. The
-   * emitter uses this set to generate the [:ObjectInterceptor:] class
-   * whose members just forward the call to the intercepted receiver.
-   */
-  final Set<Selector> usedInterceptors;
-
-  /**
    * A collection of selectors that must have a one shot interceptor
    * generated.
    */
@@ -163,9 +268,40 @@
   /// dart:mirrors has been loaded.
   FunctionElement preserveNamesMarker;
 
+  /// Holds the method "preserveMetadata" in js_mirrors when
+  /// dart:mirrors has been loaded.
+  FunctionElement preserveMetadataMarker;
+
+  /// True if a call to preserveMetadataMarker has been seen.  This means that
+  /// metadata must be retained for dart:mirrors to work correctly.
+  bool mustRetainMetadata = false;
+
+  /// True if any metadata has been retained.  This is slightly different from
+  /// [mustRetainMetadata] and tells us if any metadata was retained.  For
+  /// example, if [mustRetainMetadata] is true but there is no metadata in the
+  /// program, this variable will stil be false.
+  bool hasRetainedMetadata = false;
+
+  /// True if a call to preserveNames has been seen.
+  bool mustPreserveNames = false;
+
+  /// True if a call to disableTreeShaking has been seen.
+  bool isTreeShakingDisabled = false;
+
+  /// List of instantiated types from metadata.  If metadata must be preserved,
+  /// these types must registered.
+  final List<Dependency> metadataInstantiatedTypes = <Dependency>[];
+
+  /// List of elements used from metadata.  If metadata must be preserved,
+  /// these elements must be compiled.
+  final List<Element> metadataStaticUse = <Element>[];
+
+  /// List of tear-off functions referenced from metadata.  If metadata must be
+  /// preserved, these elements must be compiled.
+  final List<FunctionElement> metadataGetOfStaticFunction = <FunctionElement>[];
+
   JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval)
       : namer = determineNamer(compiler),
-        usedInterceptors = new Set<Selector>(),
         oneShotInterceptors = new Map<String, Selector>(),
         interceptedElements = new Map<SourceString, Set<Element>>(),
         rti = new RuntimeTypes(compiler),
@@ -193,10 +329,6 @@
     return false;
   }
 
-  void addInterceptedSelector(Selector selector) {
-    usedInterceptors.add(selector);
-  }
-
   String registerOneShotInterceptor(Selector selector) {
     Set<ClassElement> classes = getInterceptedClassesOn(selector.name);
     String name = namer.getOneShotInterceptorName(selector, classes);
@@ -609,8 +741,11 @@
     enqueueInResolution(getCyclicThrowHelper(), elements);
   }
 
-  void registerTypeLiteral(TreeElements elements) {
+  void registerTypeLiteral(Element element, TreeElements elements) {
     enqueueInResolution(getCreateRuntimeType(), elements);
+    // TODO(ahe): Might want to register [element] as an instantiated class
+    // when reflection is used.  However, as long as we disable tree-shaking
+    // eagerly it doesn't matter.
   }
 
   void registerStackTraceInCatch(TreeElements elements) {
@@ -625,25 +760,72 @@
     enqueueInResolution(getGetRuntimeTypeArgument(), elements);
   }
 
-  void registerRuntimeType(TreeElements elements) {
+  void registerGenericCallMethod(Element callMethod,
+                                 Enqueuer enqueuer, TreeElements elements) {
+    if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) {
+      registerComputeSignature(enqueuer, elements);
+    }
+  }
+
+  void registerGenericClosure(Element closure,
+                              Enqueuer enqueuer, TreeElements elements) {
+    if (enqueuer.isResolutionQueue || methodNeedsRti(closure)) {
+      registerComputeSignature(enqueuer, elements);
+    }
+  }
+
+  void registerComputeSignature(Enqueuer enqueuer, TreeElements elements) {
+    // Calls to [:computeSignature:] are generated by the emitter and we
+    // therefore need to enqueue the used elements in the codegen enqueuer as
+    // well as in the resolution enqueuer.
+    enqueue(enqueuer, getSetRuntimeTypeInfo(), elements);
+    enqueue(enqueuer, getGetRuntimeTypeInfo(), elements);
+    enqueue(enqueuer, getComputeSignature(), elements);
+    enqueue(enqueuer, getGetRuntimeTypeArguments(), elements);
+    enqueuer.registerInstantiatedClass(compiler.listClass, elements);
+  }
+
+  void registerRuntimeType(Enqueuer enqueuer, TreeElements elements) {
+    registerComputeSignature(enqueuer, elements);
     enqueueInResolution(getSetRuntimeTypeInfo(), elements);
     enqueueInResolution(getGetRuntimeTypeInfo(), elements);
-    enqueueInResolution(getGetRuntimeTypeArgument(), elements);
+    registerGetRuntimeTypeArgument(elements);
     compiler.enqueuer.resolution.registerInstantiatedClass(
         compiler.listClass, elements);
   }
 
   void registerTypeVariableExpression(TreeElements elements) {
-    registerRuntimeType(elements);
+    enqueueInResolution(getSetRuntimeTypeInfo(), elements);
+    enqueueInResolution(getGetRuntimeTypeInfo(), elements);
+    registerGetRuntimeTypeArgument(elements);
+    compiler.enqueuer.resolution.registerInstantiatedClass(
+        compiler.listClass, elements);
     enqueueInResolution(getRuntimeTypeToString(), elements);
     enqueueInResolution(getCreateRuntimeType(), elements);
   }
 
   void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) {
+    type = type.unalias(compiler);
     world.registerInstantiatedClass(compiler.boolClass, elements);
-    bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE;
     bool inCheckedMode = compiler.enableTypeAssertions;
-    if (!type.isRaw || isTypeVariable) {
+    // [registerIsCheck] is also called for checked mode checks, so we
+    // need to register checked mode helpers.
+    if (inCheckedMode) {
+      CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false);
+      if (helper != null) world.addToWorkList(helper.getElement(compiler));
+      // We also need the native variant of the check (for DOM types).
+      helper = getNativeCheckedModeHelper(type, typeCast: false);
+      if (helper != null) world.addToWorkList(helper.getElement(compiler));
+      if (type.isMalformed) {
+        enqueueInResolution(getThrowMalformedSubtypeError(), elements);
+        return;
+      }
+    } else if (type.isMalformed) {
+      registerThrowRuntimeError(elements);
+      return;
+    }
+    bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE;
+    if (!type.isRaw || type.containsTypeVariables) {
       enqueueInResolution(getSetRuntimeTypeInfo(), elements);
       enqueueInResolution(getGetRuntimeTypeInfo(), elements);
       enqueueInResolution(getGetRuntimeTypeArgument(), elements);
@@ -659,14 +841,8 @@
       }
       world.registerInstantiatedClass(compiler.listClass, elements);
     }
-    // [registerIsCheck] is also called for checked mode checks, so we
-    // need to register checked mode helpers.
-    if (inCheckedMode) {
-      Element e = getCheckedModeHelper(type, typeCast: false);
-      if (e != null) world.addToWorkList(e);
-      // We also need the native variant of the check (for DOM types).
-      e = getNativeCheckedModeHelper(type, typeCast: false);
-      if (e != null) world.addToWorkList(e);
+    if (type is FunctionType) {
+      enqueueInResolution(getCheckFunctionSubtype(), elements);
     }
     if (type.element.isNative()) {
       // We will neeed to add the "$is" and "$as" properties on the
@@ -675,14 +851,17 @@
       world.addToWorkList(
           compiler.findHelper(const SourceString('defineProperty')));
     }
-  }
+   }
 
   void registerAsCheck(DartType type, TreeElements elements) {
-    Element e = getCheckedModeHelper(type, typeCast: true);
-    enqueueInResolution(e, elements);
+    type = type.unalias(compiler);
+    CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: true);
+    enqueueInResolution(helper.getElement(compiler), elements);
     // We also need the native variant of the check (for DOM types).
-    e = getNativeCheckedModeHelper(type, typeCast: true);
-    enqueueInResolution(e, elements);
+    helper = getNativeCheckedModeHelper(type, typeCast: true);
+    if (helper != null) {
+      enqueueInResolution(helper.getElement(compiler), elements);
+    }
   }
 
   void registerThrowNoSuchMethod(TreeElements elements) {
@@ -746,7 +925,7 @@
     rti.classesUsingTypeVariableExpression.add(cls);
   }
 
-  bool needsRti(ClassElement cls) {
+  bool classNeedsRti(ClassElement cls) {
     return rti.classesNeedingRti.contains(cls.declaration) ||
         compiler.enabledRuntimeType;
   }
@@ -766,11 +945,20 @@
         || classElement == jsNullClass;
   }
 
+  bool methodNeedsRti(FunctionElement function) {
+    return rti.methodsNeedingRti.contains(function) ||
+           compiler.enabledRuntimeType;
+  }
+
+  void enqueue(Enqueuer enqueuer, Element e, TreeElements elements) {
+    enqueuer.addToWorkList(e);
+    elements.registerDependency(e);
+  }
+
   void enqueueInResolution(Element e, TreeElements elements) {
     if (e == null) return;
     ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution;
-    enqueuer.addToWorkList(e);
-    elements.registerDependency(e);
+    enqueue(enqueuer, e, elements);
   }
 
   void registerConstantMap(TreeElements elements) {
@@ -869,10 +1057,9 @@
    * the resolver with interface types (int, String, ...), and by the SSA
    * backend with implementation types (JSInt, JSString, ...).
    */
-  Element getCheckedModeHelper(DartType type, {bool typeCast}) {
-    SourceString name = getCheckedModeHelperName(
+  CheckedModeHelper getCheckedModeHelper(DartType type, {bool typeCast}) {
+    return getCheckedModeHelperInternal(
         type, typeCast: typeCast, nativeCheckOnly: false);
-    return compiler.findHelper(name);
   }
 
   /**
@@ -880,20 +1067,19 @@
    * check/type cast on [type] at runtime. If no native helper exists for
    * [type], [:null:] is returned.
    */
-  Element getNativeCheckedModeHelper(DartType type, {bool typeCast}) {
-    SourceString sourceName = getCheckedModeHelperName(
+  CheckedModeHelper getNativeCheckedModeHelper(DartType type, {bool typeCast}) {
+    return getCheckedModeHelperInternal(
         type, typeCast: typeCast, nativeCheckOnly: true);
-    if (sourceName == null) return null;
-    return compiler.findHelper(sourceName);
   }
 
   /**
-   * Returns the name of the type check/type cast helper method for [type]. If
+   * Returns the checked mode helper for the type check/type cast for [type]. If
    * [nativeCheckOnly] is [:true:], only names for native helpers are returned.
    */
-  SourceString getCheckedModeHelperName(DartType type,
-                                        {bool typeCast,
-                                         bool nativeCheckOnly}) {
+  CheckedModeHelper getCheckedModeHelperInternal(DartType type,
+                                                 {bool typeCast,
+                                                  bool nativeCheckOnly}) {
+    assert(type.kind != TypeKind.TYPEDEF);
     Element element = type.element;
     bool nativeCheck = nativeCheckOnly ||
         emitter.nativeEmitter.requiresNativeIsCheck(element);
@@ -902,94 +1088,122 @@
       // with a malformed argument type.
       if (nativeCheckOnly) return null;
       return typeCast
-          ? const SourceString('malformedTypeCast')
-          : const SourceString('malformedTypeCheck');
+          ? const MalformedCheckedModeHelper(
+              const SourceString('malformedTypeCast'))
+          : const MalformedCheckedModeHelper(
+              const SourceString('malformedTypeCheck'));
     } else if (type == compiler.types.voidType) {
       assert(!typeCast); // Cannot cast to void.
       if (nativeCheckOnly) return null;
-      return const SourceString('voidTypeCheck');
+      return const CheckedModeHelper(const SourceString('voidTypeCheck'));
     } else if (element == jsStringClass || element == compiler.stringClass) {
       if (nativeCheckOnly) return null;
       return typeCast
-          ? const SourceString("stringTypeCast")
-          : const SourceString('stringTypeCheck');
+          ? const CheckedModeHelper(const SourceString("stringTypeCast"))
+          : const CheckedModeHelper(const SourceString('stringTypeCheck'));
     } else if (element == jsDoubleClass || element == compiler.doubleClass) {
       if (nativeCheckOnly) return null;
       return typeCast
-          ? const SourceString("doubleTypeCast")
-          : const SourceString('doubleTypeCheck');
+          ? const CheckedModeHelper(const SourceString("doubleTypeCast"))
+          : const CheckedModeHelper(const SourceString('doubleTypeCheck'));
     } else if (element == jsNumberClass || element == compiler.numClass) {
       if (nativeCheckOnly) return null;
       return typeCast
-          ? const SourceString("numTypeCast")
-          : const SourceString('numTypeCheck');
+          ? const CheckedModeHelper(const SourceString("numTypeCast"))
+          : const CheckedModeHelper(const SourceString('numTypeCheck'));
     } else if (element == jsBoolClass || element == compiler.boolClass) {
       if (nativeCheckOnly) return null;
       return typeCast
-          ? const SourceString("boolTypeCast")
-          : const SourceString('boolTypeCheck');
+          ? const CheckedModeHelper(const SourceString("boolTypeCast"))
+          : const CheckedModeHelper(const SourceString('boolTypeCheck'));
     } else if (element == jsIntClass || element == compiler.intClass) {
       if (nativeCheckOnly) return null;
-      return typeCast ?
-          const SourceString("intTypeCast") :
-          const SourceString('intTypeCheck');
+      return typeCast
+          ? const CheckedModeHelper(const SourceString("intTypeCast"))
+          : const CheckedModeHelper(const SourceString('intTypeCheck'));
     } else if (Elements.isNumberOrStringSupertype(element, compiler)) {
       if (nativeCheck) {
         return typeCast
-            ? const SourceString("numberOrStringSuperNativeTypeCast")
-            : const SourceString('numberOrStringSuperNativeTypeCheck');
+            ? const PropertyCheckedModeHelper(
+                const SourceString("numberOrStringSuperNativeTypeCast"))
+            : const PropertyCheckedModeHelper(
+                const SourceString('numberOrStringSuperNativeTypeCheck'));
       } else {
         return typeCast
-          ? const SourceString("numberOrStringSuperTypeCast")
-          : const SourceString('numberOrStringSuperTypeCheck');
+          ? const PropertyCheckedModeHelper(
+              const SourceString("numberOrStringSuperTypeCast"))
+          : const PropertyCheckedModeHelper(
+              const SourceString('numberOrStringSuperTypeCheck'));
       }
     } else if (Elements.isStringOnlySupertype(element, compiler)) {
       if (nativeCheck) {
         return typeCast
-            ? const SourceString("stringSuperNativeTypeCast")
-            : const SourceString('stringSuperNativeTypeCheck');
+            ? const PropertyCheckedModeHelper(
+                const SourceString("stringSuperNativeTypeCast"))
+            : const PropertyCheckedModeHelper(
+                const SourceString('stringSuperNativeTypeCheck'));
       } else {
         return typeCast
-            ? const SourceString("stringSuperTypeCast")
-            : const SourceString('stringSuperTypeCheck');
+            ? const PropertyCheckedModeHelper(
+                const SourceString("stringSuperTypeCast"))
+            : const PropertyCheckedModeHelper(
+                const SourceString('stringSuperTypeCheck'));
       }
     } else if ((element == compiler.listClass || element == jsArrayClass) &&
                type.isRaw) {
       if (nativeCheckOnly) return null;
       return typeCast
-          ? const SourceString("listTypeCast")
-          : const SourceString('listTypeCheck');
+          ? const CheckedModeHelper(const SourceString("listTypeCast"))
+          : const CheckedModeHelper(const SourceString('listTypeCheck'));
     } else {
       if (Elements.isListSupertype(element, compiler)) {
         if (nativeCheck) {
           return typeCast
-              ? const SourceString("listSuperNativeTypeCast")
-              : const SourceString('listSuperNativeTypeCheck');
+              ? const PropertyCheckedModeHelper(
+                  const SourceString("listSuperNativeTypeCast"))
+              : const PropertyCheckedModeHelper(
+                  const SourceString('listSuperNativeTypeCheck'));
         } else {
           return typeCast
-              ? const SourceString("listSuperTypeCast")
-              : const SourceString('listSuperTypeCheck');
+              ? const PropertyCheckedModeHelper(
+                  const SourceString("listSuperTypeCast"))
+              : const PropertyCheckedModeHelper(
+                  const SourceString('listSuperTypeCheck'));
         }
       } else {
         if (nativeCheck) {
           // TODO(karlklose): can we get rid of this branch when we use
           // interceptors?
           return typeCast
-              ? const SourceString("interceptedTypeCast")
-              : const SourceString('interceptedTypeCheck');
+              ? const PropertyCheckedModeHelper(
+                  const SourceString("interceptedTypeCast"))
+              : const PropertyCheckedModeHelper(
+                  const SourceString('interceptedTypeCheck'));
         } else {
           if (type.kind == TypeKind.INTERFACE && !type.isRaw) {
             return typeCast
-                ? const SourceString('subtypeCast')
-                : const SourceString('assertSubtype');
+                ? const SubtypeCheckedModeHelper(
+                    const SourceString('subtypeCast'))
+                : const SubtypeCheckedModeHelper(
+                    const SourceString('assertSubtype'));
           } else if (type.kind == TypeKind.TYPE_VARIABLE) {
             return typeCast
-                ? const SourceString('subtypeOfRuntimeTypeCast')
-                : const SourceString('assertSubtypeOfRuntimeType');
+                ? const TypeVariableCheckedModeHelper(
+                    const SourceString('subtypeOfRuntimeTypeCast'))
+                : const TypeVariableCheckedModeHelper(
+                    const SourceString('assertSubtypeOfRuntimeType'));
+          } else if (type.kind == TypeKind.FUNCTION) {
+            return typeCast
+                ? const FunctionTypeCheckedModeHelper(
+                    const SourceString('functionSubtypeCast'))
+                : const FunctionTypeCheckedModeHelper(
+                    const SourceString('assertFunctionSubtype'));
           } else {
             return typeCast
-                ? const SourceString('propertyTypeCast')
-                : const SourceString('propertyTypeCheck');
+                ? const PropertyCheckedModeHelper(
+                    const SourceString('propertyTypeCast'))
+                : const PropertyCheckedModeHelper(
+                    const SourceString('propertyTypeCheck'));
           }
         }
       }
@@ -1004,6 +1218,10 @@
     return compiler.findHelper(const SourceString('throwRuntimeError'));
   }
 
+  Element getMalformedTypeCheck() {
+    return compiler.findHelper(const SourceString('malformedTypeCheck'));
+  }
+
   Element getThrowMalformedSubtypeError() {
     return compiler.findHelper(
         const SourceString('throwMalformedSubtypeError'));
@@ -1046,6 +1264,14 @@
     return compiler.findHelper(const SourceString('getRuntimeTypeInfo'));
   }
 
+  Element getComputeSignature() {
+    return compiler.findHelper(const SourceString('computeSignature'));
+  }
+
+  Element getGetRuntimeTypeArguments() {
+    return compiler.findHelper(const SourceString('getRuntimeTypeArguments'));
+  }
+
   Element getGetRuntimeTypeArgument() {
     return compiler.findHelper(const SourceString('getRuntimeTypeArgument'));
   }
@@ -1071,6 +1297,10 @@
         const SourceString('assertSubtypeOfRuntimeType'));
   }
 
+  Element getCheckFunctionSubtype() {
+    return compiler.findHelper(const SourceString('checkFunctionSubtype'));
+  }
+
   Element getThrowNoSuchMethod() {
     return compiler.findHelper(const SourceString('throwNoSuchMethod'));
   }
@@ -1122,19 +1352,102 @@
   ClassElement get boolImplementation => jsBoolClass;
   ClassElement get nullImplementation => jsNullClass;
 
-  void enableMirrors() {
-    LibraryElement library = compiler.libraries['dart:_js_mirrors'];
-    disableTreeShakingMarker =
-        library.find(const SourceString('disableTreeShaking'));
-    preserveNamesMarker =
-        library.find(const SourceString('preserveNames'));
- }
-
   void registerStaticUse(Element element, Enqueuer enqueuer) {
     if (element == disableTreeShakingMarker) {
       enqueuer.enqueueEverything();
+      if (isTreeShakingDisabled) return;
       compiler.disableTypeInferenceForMirrors = true;
+      isTreeShakingDisabled = true;
     } else if (element == preserveNamesMarker) {
+      if (mustPreserveNames) return;
+      mustPreserveNames = true;
+      compiler.log('Preserving names.');
+    } else if (element == preserveMetadataMarker) {
+      if (mustRetainMetadata) return;
+      compiler.log('Retaining metadata.');
+      mustRetainMetadata = true;
+      for (LibraryElement library in compiler.libraries.values) {
+        if (retainMetadataOf(library)) {
+          for (Link link = library.metadata; !link.isEmpty; link = link.tail) {
+            link.head.ensureResolved(compiler);
+          }
+        }
+      }
+      for (Dependency dependency in metadataInstantiatedTypes) {
+        registerMetadataInstantiatedType(dependency.type, dependency.user);
+      }
+      metadataInstantiatedTypes.clear();
+      for (Element e in metadataStaticUse) {
+        registerMetadataStaticUse(e);
+      }
+      metadataStaticUse.clear();
+      for (Element e in metadataGetOfStaticFunction) {
+        registerMetadataGetOfStaticFunction(e);
+      }
+      metadataGetOfStaticFunction.clear();
     }
   }
+
+  /// Called when [:const Symbol(name):] is seen.
+  void registerConstSymbol(String name, TreeElements elements) {
+  }
+
+  /// Called when [:new Symbol(...):] is seen.
+  void registerNewSymbol(TreeElements elements) {
+  }
+
+  bool retainGetter(Element element) => isTreeShakingDisabled;
+
+  bool retainSetter(Element element) => isTreeShakingDisabled;
+
+  bool retainName(SourceString name) => mustPreserveNames;
+
+  bool retainMetadataOf(Element element) {
+    if (mustRetainMetadata) hasRetainedMetadata = true;
+    return mustRetainMetadata;
+  }
+
+  void onLibraryScanned(LibraryElement library, Uri uri) {
+    if (uri == Uri.parse('dart:_js_mirrors')) {
+      disableTreeShakingMarker =
+          library.find(const SourceString('disableTreeShaking'));
+      preserveMetadataMarker =
+          library.find(const SourceString('preserveMetadata'));
+    } else if (uri == Uri.parse('dart:_js_names')) {
+      preserveNamesMarker =
+          library.find(const SourceString('preserveNames'));
+    }
+  }
+
+  void registerMetadataInstantiatedType(DartType type, TreeElements elements) {
+    if (mustRetainMetadata) {
+      compiler.constantHandler.registerInstantiatedType(type, elements);
+    } else {
+      metadataInstantiatedTypes.add(new Dependency(type, elements));
+    }
+  }
+
+  void registerMetadataStaticUse(Element element) {
+    if (mustRetainMetadata) {
+      compiler.constantHandler.registerStaticUse(element);
+    } else {
+      metadataStaticUse.add(element);
+    }
+  }
+
+  void registerMetadataGetOfStaticFunction(FunctionElement element) {
+    if (mustRetainMetadata) {
+      compiler.constantHandler.registerGetOfStaticFunction(element);
+    } else {
+      metadataGetOfStaticFunction.add(element);
+    }
+  }
+}
+
+/// Records that [type] is used by [user.element].
+class Dependency {
+  final DartType type;
+  final TreeElements user;
+
+  const Dependency(this.type, this.user);
 }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
index 2b4d152..c3cff04 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
@@ -209,11 +209,12 @@
   }
 
   jsAst.Expression visitList(ListConstant constant) {
-    return new jsAst.Call(
+    jsAst.Expression value = new jsAst.Call(
         new jsAst.PropertyAccess.field(
             new jsAst.VariableUse(namer.isolateName),
             'makeConstantList'),
         [new jsAst.ArrayInitializer.from(_array(constant.entries))]);
+    return maybeAddTypeArguments(constant.type, value);
   }
 
   String getJsConstructor(ClassElement element) {
@@ -276,23 +277,27 @@
       badFieldCountError();
     }
 
-    return new jsAst.New(
+    jsAst.Expression value = new jsAst.New(
         new jsAst.VariableUse(getJsConstructor(classElement)),
         arguments);
+    return maybeAddTypeArguments(constant.type, value);
+  }
+
+  JavaScriptBackend get backend => compiler.backend;
+
+  jsAst.PropertyAccess getHelperProperty(Element helper) {
+    String helperName = backend.namer.getName(helper);
+    return new jsAst.PropertyAccess.field(
+        new jsAst.VariableUse(namer.CURRENT_ISOLATE),
+        helperName);
   }
 
   jsAst.Expression visitType(TypeConstant constant) {
-    JavaScriptBackend backend = compiler.backend;
-    Element helper = backend.getCreateRuntimeType();
-    String helperName = backend.namer.getName(helper);
     DartType type = constant.representedType;
     String name = namer.getRuntimeTypeName(type.element);
     jsAst.Expression typeName = new jsAst.LiteralString("'$name'");
-    return new jsAst.Call(
-        new jsAst.PropertyAccess.field(
-            new jsAst.VariableUse(namer.CURRENT_ISOLATE),
-            helperName),
-        [typeName]);
+    return new jsAst.Call(getHelperProperty(backend.getCreateRuntimeType()),
+                          [typeName]);
   }
 
   jsAst.Expression visitInterceptor(InterceptorConstant constant) {
@@ -303,9 +308,10 @@
   }
 
   jsAst.Expression visitConstructed(ConstructedConstant constant) {
-    return new jsAst.New(
+    jsAst.New instantiation = new jsAst.New(
         new jsAst.VariableUse(getJsConstructor(constant.type.element)),
         _array(constant.fields));
+    return maybeAddTypeArguments(constant.type, instantiation);
   }
 
   List<jsAst.Expression> _array(List<Constant> values) {
@@ -315,4 +321,22 @@
     }
     return valueList;
   }
+
+  jsAst.Expression maybeAddTypeArguments(InterfaceType type,
+                                         jsAst.Expression value) {
+    if (type is InterfaceType &&
+        !type.isRaw &&
+        backend.classNeedsRti(type.element)) {
+      InterfaceType interface = type;
+      RuntimeTypes rti = backend.rti;
+      Iterable<String> arguments = interface.typeArguments
+          .toList(growable: false)
+          .map((DartType type) => rti.getTypeRepresentation(type, (_){}));
+      jsAst.Expression argumentList =
+          new jsAst.LiteralString('[${arguments.join(', ')}]');
+      return new jsAst.Call(getHelperProperty(backend.getSetRuntimeTypeInfo()),
+                            [value, argumentList]);
+    }
+    return value;
+  }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 7721152..0a2f53a 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -48,6 +48,13 @@
   }
 }
 
+// Function signatures used in the generation of runtime type information.
+typedef void FunctionTypeSignatureEmitter(Element method,
+                                          FunctionType methodType);
+// TODO(johnniwinther): Clean up terminology for rti in the emitter.
+typedef void FunctionTypeTestEmitter(FunctionType functionType);
+typedef void SubstitutionEmitter(Element element, {bool emitNull});
+
 /**
  * Generates the code for all used classes in the program. Static fields (even
  * in classes) are ignored, since they can be treated as non-class elements.
@@ -75,6 +82,8 @@
   final List<ClassElement> nativeClasses = <ClassElement>[];
   final List<Selector> trivialNsmHandlers = <Selector>[];
   final Map<String, String> mangledFieldNames = <String, String>{};
+  final Set<String> recordedMangledNames = new Set<String>();
+  final Set<String> interceptorInvocationNames = new Set<String>();
 
   // TODO(ngeoffray): remove this field.
   Set<ClassElement> instantiatedClasses;
@@ -110,11 +119,26 @@
   Set<ClassElement> checkedClasses;
 
   /**
-   * Raw Typedef symbols occuring in is-checks and type assertions.  If the
-   * program contains `x is F<int>` and `x is F<bool>` then the TypedefElement
-   * `F` will occur once in [checkedTypedefs].
+   * The set of function types that checked, both explicity through tests of
+   * typedefs and implicitly through type annotations in checked mode.
    */
-  Set<TypedefElement> checkedTypedefs;
+  Set<FunctionType> checkedFunctionTypes;
+
+  Map<ClassElement, Set<FunctionType>> checkedGenericFunctionTypes =
+      new Map<ClassElement, Set<FunctionType>>();
+
+  Set<FunctionType> checkedNonGenericFunctionTypes =
+      new Set<FunctionType>();
+
+  void registerDynamicFunctionTypeCheck(FunctionType functionType) {
+    ClassElement classElement = Types.getClassContext(functionType);
+    if (classElement != null) {
+      checkedGenericFunctionTypes.putIfAbsent(classElement,
+          () => new Set<FunctionType>()).add(functionType);
+    } else {
+      checkedNonGenericFunctionTypes.add(functionType);
+    }
+  }
 
   final bool generateSourceMap;
 
@@ -145,18 +169,20 @@
   }
 
   void computeRequiredTypeChecks() {
-    assert(checkedClasses == null && checkedTypedefs == null);
+    assert(checkedClasses == null && checkedFunctionTypes == null);
 
     backend.rti.addImplicitChecks(compiler.codegenWorld,
                                   classesUsingTypeVariableTests);
 
     checkedClasses = new Set<ClassElement>();
-    checkedTypedefs = new Set<TypedefElement>();
+    checkedFunctionTypes = new Set<FunctionType>();
     compiler.codegenWorld.isChecks.forEach((DartType t) {
-      if (t is InterfaceType) {
-        checkedClasses.add(t.element);
-      } else if (t is TypedefType) {
-        checkedTypedefs.add(t.element);
+      if (!t.isMalformed) {
+        if (t is InterfaceType) {
+          checkedClasses.add(t.element);
+        } else if (t is FunctionType) {
+          checkedFunctionTypes.add(t);
+        }
       }
     });
   }
@@ -615,7 +641,7 @@
            */
           js('var classData = desc[""], supr, name = cls, fields = classData'),
           optional(
-              compiler.mirrorsEnabled,
+              backend.hasRetainedMetadata,
               js.if_('typeof classData == "object" && '
                      'classData instanceof Array',
                      [js('classData = fields = classData[0]')])),
@@ -649,7 +675,7 @@
           ])),
 
           js('var constructor = defineClass(name, cls, fields, desc)'),
-          optional(compiler.mirrorsEnabled,
+          optional(backend.hasRetainedMetadata,
                    js('constructor["${namer.metadataField}"] = desc')),
           js('isolateProperties[cls] = constructor'),
           js.if_('supr', js('pendingClasses[cls] = supr'))
@@ -958,6 +984,7 @@
       count++;
       parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName);
       argumentsBuffer[0] = js(receiverArgumentName);
+      interceptorInvocationNames.add(invocationName);
     }
 
     int optionalParameterStart = positionalArgumentCount + extraArgumentCount;
@@ -1015,6 +1042,11 @@
     jsAst.Fun function = js.fun(parametersBuffer, body);
 
     defineStub(invocationName, function);
+
+    String reflectionName = getReflectionName(selector, invocationName);
+    if (reflectionName != null) {
+      defineStub('+$reflectionName', js('0'));
+    }
   }
 
   void addParameterStubs(FunctionElement member,
@@ -1132,7 +1164,7 @@
   bool instanceFieldNeedsGetter(Element member) {
     assert(member.isField());
     if (fieldAccessNeverThrows(member)) return false;
-    return compiler.mirrorsEnabled
+    return backend.retainGetter(member)
         || compiler.codegenWorld.hasInvokedGetter(member, compiler);
   }
 
@@ -1140,7 +1172,7 @@
     assert(member.isField());
     if (fieldAccessNeverThrows(member)) return false;
     return (!member.modifiers.isFinalOrConst())
-        && (compiler.mirrorsEnabled
+        && (backend.retainSetter(member)
             || compiler.codegenWorld.hasInvokedSetter(member, compiler));
   }
 
@@ -1175,12 +1207,15 @@
       jsAst.Expression code = backend.generatedCode[member];
       if (code == null) return;
       String name = namer.getName(member);
+      if (backend.isInterceptedMethod(member)) {
+        interceptorInvocationNames.add(name);
+      }
       builder.addProperty(name, code);
       var metadata = buildMetadataFunction(member);
       if (metadata != null) {
         builder.addProperty('@$name', metadata);
       }
-      String reflectionName = getReflectionName(member);
+      String reflectionName = getReflectionName(member, name);
       if (reflectionName != null) {
         builder.addProperty('+$reflectionName', js('0'));
       }
@@ -1200,23 +1235,76 @@
     emitExtraAccessors(member, builder);
   }
 
-  String getReflectionName(Element element) {
-    if (!compiler.mirrorsEnabled) return null;
-    String name = element.name.slowToString();
-    if (element.isGetter()) return name;
-    if (element.isSetter()) return '$name=';
-    if (element.isFunction()) {
-      FunctionElement function = element;
-      int requiredParameterCount = function.requiredParameterCount(compiler);
-      int optionalParameterCount = function.optionalParameterCount(compiler);
-      String suffix = '$name:$requiredParameterCount:$optionalParameterCount';
-      return (function.isConstructor()) ? 'new $suffix' : suffix;
+  String getReflectionName(elementOrSelector, String mangledName) {
+    if (!backend.retainName(elementOrSelector.name)) return null;
+    // TODO(ahe): Enable the next line when I can tell the difference between
+    // an instance method and a global.  They may have the same mangled name.
+    // if (recordedMangledNames.contains(mangledName)) return null;
+    recordedMangledNames.add(mangledName);
+    return getReflectionNameInternal(elementOrSelector, mangledName);
+  }
+
+  String getReflectionNameInternal(elementOrSelector, String mangledName) {
+    String name = elementOrSelector.name.slowToString();
+    if (elementOrSelector.isGetter()) return name;
+    if (elementOrSelector.isSetter()) {
+      if (!mangledName.startsWith(namer.setterPrefix)) return '$name=';
+      String base = mangledName.substring(namer.setterPrefix.length);
+      String getter = '${namer.getterPrefix}$base';
+      mangledFieldNames[getter] = name;
+      recordedMangledNames.add(getter);
+      return null;
     }
+    if (elementOrSelector is Selector
+        || elementOrSelector.isFunction()
+        || elementOrSelector.isConstructor()) {
+      int requiredParameterCount;
+      int optionalParameterCount;
+      String namedArguments = '';
+      bool isConstructor;
+      if (elementOrSelector is Selector) {
+        Selector selector = elementOrSelector;
+        requiredParameterCount = selector.argumentCount;
+        optionalParameterCount = 0;
+        isConstructor = false;
+        namedArguments = namedParametersAsReflectionNames(selector);
+      } else {
+        FunctionElement function = elementOrSelector;
+        requiredParameterCount = function.requiredParameterCount(compiler);
+        optionalParameterCount = function.optionalParameterCount(compiler);
+        isConstructor = function.isConstructor();
+        FunctionSignature signature = function.computeSignature(compiler);
+        if (signature.optionalParametersAreNamed) {
+          var names = [];
+          for (Element e in signature.optionalParameters) {
+            names.add(e.name);
+          }
+          Selector selector = new Selector.call(
+              function.name,
+              function.getLibrary(),
+              requiredParameterCount,
+              names);
+          namedArguments = namedParametersAsReflectionNames(selector);
+        }
+      }
+      String suffix =
+          '$name:$requiredParameterCount:$optionalParameterCount'
+          '$namedArguments';
+      return (isConstructor) ? 'new $suffix' : suffix;
+    }
+    Element element = elementOrSelector;
     if (element.isGenerativeConstructorBody()) {
       return null;
     }
     throw compiler.internalErrorOnElement(
-        element, 'Do not know how to reflect on this');
+        element, 'Do not know how to reflect on this $element');
+  }
+
+  String namedParametersAsReflectionNames(Selector selector) {
+    if (selector.orderedNamedArguments.isEmpty) return '';
+    String names =
+        selector.orderedNamedArguments.map((x) => x.slowToString()).join(':');
+    return ':$names';
   }
 
   /**
@@ -1263,9 +1351,34 @@
       builder.addProperty(namer.operatorIs(other), js('true'));
     }
 
+    void generateIsFunctionTypeTest(FunctionType type) {
+      String operator = namer.operatorIsType(type);
+      builder.addProperty(operator, new jsAst.LiteralBool(true));
+    }
+
+    void generateFunctionTypeSignature(Element method, FunctionType type) {
+      assert(method.isImplementation);
+      String thisAccess = 'this';
+      Node node = method.parseNode(compiler);
+      ClosureClassMap closureData =
+          compiler.closureToClassMapper.closureMappingCache[node];
+      if (closureData != null) {
+        Element thisElement =
+            closureData.freeVariableMapping[closureData.thisElement];
+        if (thisElement != null) {
+          String thisName = backend.namer.getName(thisElement);
+          thisAccess = 'this.$thisName';
+        }
+      }
+      RuntimeTypes rti = backend.rti;
+      String encoding = rti.getSignatureEncoding(type, () => '$thisAccess');
+      String operatorSignature = namer.operatorSignature();
+      builder.addProperty(operatorSignature,
+          new jsAst.LiteralExpression(encoding));
+    }
+
     void generateSubstitution(Element other, {bool emitNull: false}) {
       RuntimeTypes rti = backend.rti;
-      // TODO(karlklose): support typedefs with variables.
       jsAst.Expression expression;
       bool needsNativeCheck = nativeEmitter.requiresNativeIsCheck(other);
       if (other.kind == ElementKind.CLASS) {
@@ -1282,7 +1395,9 @@
       }
     }
 
-    generateIsTestsOn(classElement, generateIsTest, generateSubstitution);
+    generateIsTestsOn(classElement, generateIsTest,
+        generateIsFunctionTypeTest, generateFunctionTypeSignature,
+        generateSubstitution);
   }
 
   void emitRuntimeTypeSupport(CodeBuffer buffer) {
@@ -1302,6 +1417,17 @@
         }
       };
     }
+
+    void addSignature(FunctionType type) {
+      String encoding = rti.getTypeEncoding(type);
+      buffer.add('${namer.signatureName(type)}$_=${_}$encoding$N');
+    }
+
+    checkedNonGenericFunctionTypes.forEach(addSignature);
+
+    checkedGenericFunctionTypes.forEach((_, Set<FunctionType> functionTypes) {
+      functionTypes.forEach(addSignature);
+    });
   }
 
   /**
@@ -1433,12 +1559,14 @@
     DartType type = member.computeType(compiler);
     // TODO(ahe): Generate a dynamic type error here.
     if (type.element.isErroneous()) return;
-    FunctionElement helperElement
-        = backend.getCheckedModeHelper(type, typeCast: false);
+    type = type.unalias(compiler);
+    CheckedModeHelper helper =
+        backend.getCheckedModeHelper(type, typeCast: false);
+    FunctionElement helperElement = helper.getElement(compiler);
     String helperName = namer.isolateAccess(helperElement);
     List<jsAst.Expression> arguments = <jsAst.Expression>[js('v')];
     if (helperElement.computeSignature(compiler).parameterCount != 1) {
-      arguments.add(js.string(namer.operatorIs(type.element)));
+      arguments.add(js.string(namer.operatorIsType(type)));
     }
 
     String setterName = namer.setterNameFromAccessorName(accessorName);
@@ -1467,16 +1595,12 @@
   void recordMangledField(Element member,
                           String accessorName,
                           String memberName) {
+    if (!backend.retainGetter(member)) return;
     String previousName = mangledFieldNames.putIfAbsent(
         '${namer.getterPrefix}$accessorName',
         () => memberName);
     assert(invariant(member, previousName == memberName,
                      message: '$previousName != ${memberName}'));
-    previousName = mangledFieldNames.putIfAbsent(
-        '${namer.setterPrefix}$accessorName',
-        () => '${memberName}=');
-    assert(invariant(member, previousName == '${memberName}=',
-                     message: '$previousName != ${memberName}='));
   }
 
   /// Returns `true` if fields added.
@@ -1512,18 +1636,14 @@
       if (!classIsNative || needsAccessor) {
         buffer.write(separator);
         separator = ',';
-        if (compiler.mirrorsEnabled) {
-          var metadata = buildMetadataFunction(member);
-          if (metadata != null) {
-            hasMetadata = true;
-          } else {
-            metadata = new jsAst.LiteralNull();
-          }
-          fieldMetadata.add(metadata);
+        var metadata = buildMetadataFunction(member);
+        if (metadata != null) {
+          hasMetadata = true;
+        } else {
+          metadata = new jsAst.LiteralNull();
         }
-        if (compiler.mirrorsEnabled) {
-          recordMangledField(member, accessorName, member.name.slowToString());
-        }
+        fieldMetadata.add(metadata);
+        recordMangledField(member, accessorName, member.name.slowToString());
         if (!needsAccessor) {
           // Emit field for constructor generation.
           assert(!classIsNative);
@@ -1560,7 +1680,12 @@
             assert(setterCode != 0);
           }
           int code = getterCode + (setterCode << 2);
-          buffer.write(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]);
+          if (code == 0) {
+            compiler.reportInternalError(
+                member, 'Internal error: code is 0 ($classElement/$member)');
+          } else {
+            buffer.write(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]);
+          }
         }
       }
     });
@@ -1649,6 +1774,9 @@
     }
     buffer.write('$className:$_');
     buffer.write(jsAst.prettyPrint(builder.toObjectInitializer(), compiler));
+    if (backend.retainName(classElement.name)) {
+      buffer.write(',$n$n"+${classElement.name.slowToString()}": 0');
+    }
   }
 
   bool get getterAndSetterCanBeImplementedByFieldSpec => true;
@@ -1671,14 +1799,27 @@
     return _selectorRank(selector1) - _selectorRank(selector2);
   }
 
-  Iterable<Element> getTypedefChecksOn(DartType type) {
-    bool isSubtype(TypedefElement typedef) {
-      FunctionType typedefType =
-          typedef.computeType(compiler).unalias(compiler);
-      return compiler.types.isSubtype(type, typedefType);
+  /**
+   * Returns a mapping containing all checked function types for which [type]
+   * can be a subtype. A function type is mapped to [:true:] if [type] is
+   * statically known to be a subtype of it and to [:false:] if [type] might
+   * be a subtype, provided with the right type arguments.
+   */
+  // TODO(johnniwinther): Change to return a mapping from function types to
+  // a set of variable points and use this to detect statically/dynamically
+  // known subtype relations.
+  Map<FunctionType, bool> getFunctionTypeChecksOn(DartType type) {
+    Map<FunctionType, bool> functionTypeMap =
+        new LinkedHashMap<FunctionType, bool>();
+    for (FunctionType functionType in checkedFunctionTypes) {
+      if (compiler.types.isSubtype(type, functionType)) {
+        functionTypeMap[functionType] = true;
+      } else if (compiler.types.isPotentialSubtype(type, functionType)) {
+        functionTypeMap[functionType] = false;
+      }
     }
-    return checkedTypedefs.where(isSubtype).toList()
-        ..sort(Elements.compareByPosition);
+    // TODO(johnniwinther): Ensure stable ordering of the keys.
+    return functionTypeMap;
   }
 
   /**
@@ -1690,7 +1831,9 @@
    */
   void generateIsTestsOn(ClassElement cls,
                          void emitIsTest(Element element),
-                         void emitSubstitution(Element element, {emitNull})) {
+                         FunctionTypeTestEmitter emitIsFunctionTypeTest,
+                         FunctionTypeSignatureEmitter emitFunctionTypeSignature,
+                         SubstitutionEmitter emitSubstitution) {
     if (checkedClasses.contains(cls)) {
       emitIsTest(cls);
       emitSubstitution(cls);
@@ -1713,7 +1856,7 @@
       Set<ClassElement> emitted = new Set<ClassElement>();
       // TODO(karlklose): move the computation of these checks to
       // RuntimeTypeInformation.
-      if (backend.needsRti(cls)) {
+      if (backend.classNeedsRti(cls)) {
         emitSubstitution(superclass, emitNull: true);
         emitted.add(superclass);
       }
@@ -1741,7 +1884,7 @@
     // A class that defines a [:call:] method implicitly implements
     // [Function] and needs checks for all typedefs that are used in is-checks.
     if (checkedClasses.contains(compiler.functionClass) ||
-        !checkedTypedefs.isEmpty) {
+        !checkedFunctionTypes.isEmpty) {
       Element call = cls.lookupLocalMember(Compiler.CALL_OPERATOR_NAME);
       if (call == null) {
         // If [cls] is a closure, it has a synthetic call operator method.
@@ -1752,8 +1895,12 @@
                                   emitIsTest,
                                   emitSubstitution,
                                   generated);
-        getTypedefChecksOn(call.computeType(compiler)).forEach(emitIsTest);
-      }
+        FunctionType callType = call.computeType(compiler);
+        Map<FunctionType, bool> functionTypeChecks =
+            getFunctionTypeChecksOn(callType);
+        generateFunctionTypeTests(call, callType, functionTypeChecks,
+            emitFunctionTypeSignature, emitIsFunctionTypeTest);
+     }
     }
 
     for (DartType interfaceType in cls.interfaces) {
@@ -1767,7 +1914,7 @@
    */
   void generateInterfacesIsTests(ClassElement cls,
                                  void emitIsTest(ClassElement element),
-                                 void emitSubstitution(ClassElement element),
+                                 SubstitutionEmitter emitSubstitution,
                                  Set<Element> alreadyGenerated) {
     void tryEmitTest(ClassElement check) {
       if (!alreadyGenerated.contains(check) && checkedClasses.contains(check)) {
@@ -1795,6 +1942,45 @@
     }
   }
 
+  static const int MAX_FUNCTION_TYPE_PREDICATES = 10;
+
+  /**
+   * Generates function type checks on [method] with type [methodType] against
+   * the function type checks in [functionTypeChecks].
+   */
+  void generateFunctionTypeTests(
+      Element method,
+      FunctionType methodType,
+      Map<FunctionType, bool> functionTypeChecks,
+      FunctionTypeSignatureEmitter emitFunctionTypeSignature,
+      FunctionTypeTestEmitter emitIsFunctionTypeTest) {
+    bool hasDynamicFunctionTypeCheck = false;
+    int neededPredicates = 0;
+    functionTypeChecks.forEach((FunctionType functionType, bool knownSubtype) {
+      if (!knownSubtype) {
+        registerDynamicFunctionTypeCheck(functionType);
+        hasDynamicFunctionTypeCheck = true;
+      } else {
+        neededPredicates++;
+      }
+    });
+    bool alwaysUseSignature = false;
+    if (hasDynamicFunctionTypeCheck ||
+        neededPredicates > MAX_FUNCTION_TYPE_PREDICATES) {
+      emitFunctionTypeSignature(method, methodType);
+      alwaysUseSignature = true;
+    }
+    functionTypeChecks.forEach((FunctionType functionType, bool knownSubtype) {
+      if (knownSubtype) {
+        if (alwaysUseSignature) {
+          registerDynamicFunctionTypeCheck(functionType);
+        } else {
+          emitIsFunctionTypeTest(functionType);
+        }
+      }
+    });
+  }
+
   /**
    * Return a function that returns true if its argument is a class
    * that needs to be emitted.
@@ -1879,6 +2065,10 @@
         buffer.write(',$n$n"@$name":$_');
         buffer.write(jsAst.prettyPrint(metadata, compiler));
       }
+      String reflectionName = getReflectionName(element, name);
+      if (reflectionName != null) {
+        buffer.write(',$n$n"+$reflectionName":${_}0');
+      }
       jsAst.Expression bailoutCode = backend.generatedBailoutCode[element];
       if (bailoutCode != null) {
         pendingElementsWithBailouts.remove(element);
@@ -1953,12 +2143,6 @@
 
       addParameterStubs(callElement, closureBuilder.addProperty);
 
-      DartType type = element.computeType(compiler);
-      getTypedefChecksOn(type).forEach((Element typedef) {
-        String operator = namer.operatorIs(typedef);
-        closureBuilder.addProperty(operator, js('true'));
-      });
-
       // TODO(ngeoffray): Cache common base classes for closures, bound
       // closures, and static closures that have common type checks.
       boundClosures.add(
@@ -1966,6 +2150,28 @@
               closureBuilder.toObjectInitializer()));
 
       staticGetters[element] = closureClassElement;
+
+      void emitFunctionTypeSignature(Element method, FunctionType methodType) {
+        RuntimeTypes rti = backend.rti;
+        // [:() => null:] is dummy encoding of [this] which is never needed for
+        // the encoding of the type of the static [method].
+        String encoding = rti.getSignatureEncoding(methodType, () => 'null');
+        String operatorSignature = namer.operatorSignature();
+        // TODO(johnniwinther): Make MiniJsParser support function expressions.
+        closureBuilder.addProperty(operatorSignature,
+            new jsAst.LiteralExpression(encoding));
+      }
+
+      void emitIsFunctionTypeTest(FunctionType functionType) {
+        String operator = namer.operatorIsType(functionType);
+        closureBuilder.addProperty(operator, js('true'));
+      }
+
+      FunctionType methodType = element.computeType(compiler);
+      Map<FunctionType, bool> functionTypeChecks =
+          getFunctionTypeChecksOn(methodType);
+      generateFunctionTypeTests(element, methodType, functionTypeChecks,
+          emitFunctionTypeSignature, emitIsFunctionTypeTest);
     }
   }
 
@@ -2023,12 +2229,14 @@
       fieldNames.add(namer.getName(field));
     });
 
-    Iterable<Element> typedefChecks =
-        getTypedefChecksOn(member.computeType(compiler));
-    bool hasTypedefChecks = !typedefChecks.isEmpty;
+    DartType memberType = member.computeType(compiler);
+    Map<FunctionType, bool> functionTypeChecks =
+        getFunctionTypeChecksOn(memberType);
+    bool hasFunctionTypeChecks = !functionTypeChecks.isEmpty;
 
-    bool canBeShared = !hasOptionalParameters && !hasTypedefChecks;
+    bool canBeShared = !hasOptionalParameters && !hasFunctionTypeChecks;
 
+    ClassElement classElement = member.getEnclosingClass();
     String closureClass = canBeShared ? cache[parameterCount] : null;
     if (closureClass == null) {
       // Either the class was not cached yet, or there are optional parameters.
@@ -2084,10 +2292,23 @@
       boundClosureBuilder.addProperty(invocationName, fun);
 
       addParameterStubs(callElement, boundClosureBuilder.addProperty);
-      typedefChecks.forEach((Element typedef) {
-        String operator = namer.operatorIs(typedef);
-        boundClosureBuilder.addProperty(operator, js('true'));
-      });
+
+      void emitFunctionTypeSignature(Element method, FunctionType methodType) {
+        String encoding = backend.rti.getSignatureEncoding(
+            methodType, () => 'this.${fieldNames[0]}');
+        String operatorSignature = namer.operatorSignature();
+        boundClosureBuilder.addProperty(operatorSignature,
+            new jsAst.LiteralExpression(encoding));
+      }
+
+      void emitIsFunctionTypeTest(FunctionType functionType) {
+        String operator = namer.operatorIsType(functionType);
+        boundClosureBuilder.addProperty(operator,
+            new jsAst.LiteralBool(true));
+      }
+
+      generateFunctionTypeTests(member, memberType, functionTypeChecks,
+          emitFunctionTypeSignature, emitIsFunctionTypeTest);
 
       boundClosures.add(
           js('$classesCollector.$mangledName = #',
@@ -2119,8 +2340,7 @@
     }
 
     jsAst.Expression getterFunction = js.fun(
-        parameters,
-        js.return_(js(closureClass).newWith(arguments)));
+        parameters, js.return_(js(closureClass).newWith(arguments)));
 
     defineStub(getterName, getterFunction);
   }
@@ -2160,7 +2380,6 @@
     // identical stubs for each we track untyped selectors which already have
     // stubs.
     Set<Selector> generatedSelectors = new Set<Selector>();
-
     for (Selector selector in selectors) {
       if (selector.applies(member, compiler)) {
         selector = selector.asUntyped;
@@ -2404,6 +2623,10 @@
         if (mask.willHit(selector, compiler)) continue;
         String jsName = namer.invocationMirrorInternalName(selector);
         addedJsNames[jsName] = selector;
+        String reflectionName = getReflectionName(selector, jsName);
+        if (reflectionName != null) {
+          mangledFieldNames[jsName] = reflectionName;
+        }
       }
     }
 
@@ -2761,6 +2984,15 @@
         rti.getClassesUsedInSubstitutions(backend, requiredChecks);
     addClassesWithSuperclasses(classesUsedInSubstitutions);
 
+    // 3c. Add classes that contain checked generic function types. These are
+    //     needed to store the signature encoding.
+    for (FunctionType type in checkedFunctionTypes) {
+      ClassElement contextClass = Types.getClassContext(type);
+      if (contextClass != null) {
+        neededClasses.add(contextClass);
+      }
+    }
+
     // 4. Finally, sort the classes.
     List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses);
 
@@ -2977,18 +3209,21 @@
    * method with an extra parameter.
    */
   void emitInterceptedNames(CodeBuffer buffer) {
+    // TODO(ahe): We should not generate the list of intercepted names at
+    // compile time, it can be generated automatically at runtime given
+    // subclasses of Interceptor (which can easily be identified).
     if (!compiler.enabledInvokeOn) return;
     String name = backend.namer.getName(backend.interceptedNames);
 
     int index = 0;
-    List<jsAst.ArrayElement> elements = backend.usedInterceptors.map(
-      (Selector selector) {
-        jsAst.Literal str = js.string(namer.invocationName(selector));
+    var invocationNames = interceptorInvocationNames.toList()..sort();
+    List<jsAst.ArrayElement> elements = invocationNames.map(
+      (String invocationName) {
+        jsAst.Literal str = js.string(invocationName);
         return new jsAst.ArrayElement(index++, str);
       }).toList();
-    jsAst.ArrayInitializer array = new jsAst.ArrayInitializer(
-        backend.usedInterceptors.length,
-        elements);
+    jsAst.ArrayInitializer array =
+        new jsAst.ArrayInitializer(invocationNames.length, elements);
 
     jsAst.Expression assignment = js('$isolateProperties.$name = #', array);
 
@@ -3017,17 +3252,27 @@
   /// annotated with itself.  The metadata function is used by
   /// mirrors_patch to implement DeclarationMirror.metadata.
   jsAst.Fun buildMetadataFunction(Element element) {
-    if (!compiler.mirrorsEnabled) return null;
-    var metadata = [];
-    Link link = element.metadata;
-    // TODO(ahe): Why is metadata sometimes null?
-    if (link != null) {
-      for (; !link.isEmpty; link = link.tail) {
-        metadata.add(constantReference(link.head.value));
+    if (!backend.retainMetadataOf(element)) return null;
+    return compiler.withCurrentElement(element, () {
+      var metadata = [];
+      Link link = element.metadata;
+      // TODO(ahe): Why is metadata sometimes null?
+      if (link != null) {
+        for (; !link.isEmpty; link = link.tail) {
+          MetadataAnnotation annotation = link.head;
+          Constant value = annotation.value;
+          if (value == null) {
+            compiler.reportInternalError(
+                annotation, 'Internal error: value is null');
+          } else {
+            metadata.add(constantReference(value));
+          }
+        }
       }
-    }
-    if (metadata.isEmpty) return null;
-    return js.fun([], [js.return_(new jsAst.ArrayInitializer.from(metadata))]);
+      if (metadata.isEmpty) return null;
+      return js.fun(
+          [], [js.return_(new jsAst.ArrayInitializer.from(metadata))]);
+    });
   }
 
   String assembleProgram() {
@@ -3174,13 +3419,16 @@
       emitStaticFunctionGetters(mainBuffer);
 
       emitRuntimeTypeSupport(mainBuffer);
+      emitGetInterceptorMethods(mainBuffer);
+      // Constants in checked mode call into RTI code to set type information
+      // which may need getInterceptor methods, so we have to make sure that
+      // [emitGetInterceptorMethods] has been called.
       emitCompileTimeConstants(mainBuffer);
       // Static field initializations require the classes and compile-time
       // constants to be set up.
       emitStaticNonFinalFieldInitializations(mainBuffer);
       emitOneShotInterceptors(mainBuffer);
       emitInterceptedNames(mainBuffer);
-      emitGetInterceptorMethods(mainBuffer);
       emitLazilyInitializedStaticFields(mainBuffer);
 
       mainBuffer.add(nativeBuffer);
@@ -3333,8 +3581,12 @@
 (function (reflectionData) {
   if (!init.libraries) init.libraries = [];
   if (!init.mangledNames) init.mangledNames = {};
+  if (!init.mangledGlobalNames) init.mangledGlobalNames = {};
+  init.getterPrefix = "${namer.getterPrefix}";
+  init.setterPrefix = "${namer.setterPrefix}";
   var libraries = init.libraries;
   var mangledNames = init.mangledNames;
+  var mangledGlobalNames = init.mangledGlobalNames;
   var hasOwnProperty = Object.prototype.hasOwnProperty;
   var length = reflectionData.length;
   for (var i = 0; i < length; i++) {
@@ -3348,18 +3600,23 @@
     for (var property in descriptor) {
       if (!hasOwnProperty.call(descriptor, property)) continue;
       var element = descriptor[property];
-      if (property.substring(0, 1) == "@") {
+      var firstChar = property.substring(0, 1);
+      var previousProperty;
+      if (firstChar == "+") {
+        mangledGlobalNames[previousProperty] = property.substring(1);
+      } else if (firstChar == "@") {
         property = property.substring(1);
         ${namer.CURRENT_ISOLATE}[property]["${namer.metadataField}"] = element;
       } else if (typeof element === "function") {
-        ${namer.CURRENT_ISOLATE}[property] = element;
+        ${namer.CURRENT_ISOLATE}[previousProperty = property] = element;
         functions.push(property);
       } else {
+        previousProperty = property;
         var newDesc = {};
         var previousProp;
         for (var prop in element) {
           if (!hasOwnProperty.call(element, prop)) continue;
-          var firstChar = prop.substring(0, 1);
+          firstChar = prop.substring(0, 1);
           if (firstChar == "+") {
             mangledNames[previousProp] = prop.substring(1);
           } else if (firstChar == "@" && prop != "@") {
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 77766eb..a15f5e0 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -173,6 +173,7 @@
   }
 
   final String CURRENT_ISOLATE;
+  String get GLOBAL_OBJECT => CURRENT_ISOLATE;
 
   final String getterPrefix = r'get$';
   final String setterPrefix = r'set$';
@@ -766,6 +767,41 @@
 
   String operatorAsPrefix() => r'$as';
 
+  String operatorSignature() => r'$signature';
+
+  String functionTypeTag() => r'func';
+
+  String functionTypeVoidReturnTag() => r'void';
+
+  String functionTypeReturnTypeTag() => r'ret';
+
+  String functionTypeRequiredParametersTag() => r'args';
+
+  String functionTypeOptionalParametersTag() => r'opt';
+
+  String functionTypeNamedParametersTag() => r'named';
+
+  Map<FunctionType,String> functionTypeNameMap =
+      new Map<FunctionType,String>();
+  FunctionTypeNamer functionTypeNamer = new FunctionTypeNamer();
+
+  String getFunctionTypeName(FunctionType functionType) {
+    return functionTypeNameMap.putIfAbsent(functionType, () {
+      String proposedName = functionTypeNamer.computeName(functionType);
+      String freshName = getFreshName(proposedName, usedInstanceNames,
+                                      suggestedInstanceNames, ensureSafe: true);
+      return freshName;
+    });
+  }
+
+  String operatorIsType(DartType type) {
+    if (type.kind == TypeKind.FUNCTION) {
+      // TODO(erikcorry): Reduce from $isx to ix when we are minifying.
+      return '${operatorIsPrefix()}_${getFunctionTypeName(type)}';
+    }
+    return operatorIs(type.element);
+  }
+
   String operatorIs(Element element) {
     // TODO(erikcorry): Reduce from $isx to ix when we are minifying.
     return '${operatorIsPrefix()}${getRuntimeTypeName(element)}';
@@ -787,6 +823,20 @@
     return '${operatorAsPrefix()}${getName(element)}';
   }
 
+  String signatureLocation(FunctionType type) {
+    ClassElement classElement = Types.getClassContext(type);
+    if (classElement != null) {
+      return '${isolateAccess(classElement)}';
+    } else {
+      return '${GLOBAL_OBJECT}';
+    }
+  }
+
+  String signatureName(FunctionType type) {
+    String signature = '${operatorSignature()}_${getFunctionTypeName(type)}';
+    return '${signatureLocation(type)}.$signature';
+  }
+
   String safeName(String name) => _safeName(name, jsReserved);
   String safeVariableName(String name) => _safeName(name, jsVariableReserved);
 
@@ -841,7 +891,6 @@
   }
 }
 
-
 /**
  * Generator of names for [Constant] values.
  *
@@ -1015,7 +1064,6 @@
   }
 }
 
-
 /**
  * Generates canonical hash values for [Constant]s.
  *
@@ -1161,3 +1209,56 @@
     return _MASK & (hash + (((_MASK >> 15) & hash) << 15));
   }
 }
+
+class FunctionTypeNamer extends DartTypeVisitor {
+  StringBuffer sb;
+
+  String computeName(DartType type) {
+    sb = new StringBuffer();
+    visit(type);
+    return sb.toString();
+  }
+
+  visit(DartType type) {
+    type.accept(this, null);
+  }
+
+  visitType(DartType type, _) {
+    sb.write(type.name.slowToString());
+  }
+
+  visitFunctionType(FunctionType type, _) {
+    visit(type.returnType);
+    sb.write('_');
+    for (Link<DartType> link = type.parameterTypes;
+         !link.isEmpty;
+         link = link.tail) {
+      sb.write('_');
+      visit(link.head);
+    }
+    bool first = false;
+    for (Link<DartType> link = type.optionalParameterTypes;
+         !link.isEmpty;
+         link = link.tail) {
+      if (!first) {
+        sb.write('_');
+      }
+      sb.write('_');
+      visit(link.head);
+      first = true;
+    }
+    if (!type.namedParameterTypes.isEmpty) {
+      first = false;
+      for (Link<DartType> link = type.namedParameterTypes;
+          !link.isEmpty;
+          link = link.tail) {
+        if (!first) {
+          sb.write('_');
+        }
+        sb.write('_');
+        visit(link.head);
+        first = true;
+      }
+    }
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
index c162f55..76b9efc 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -20,6 +20,7 @@
 
   final Map<ClassElement, Set<ClassElement>> rtiDependencies;
   final Set<ClassElement> classesNeedingRti;
+  final Set<Element> methodsNeedingRti;
   // The set of classes that use one of their type variables as expressions
   // to get the runtime type.
   final Set<ClassElement> classesUsingTypeVariableExpression;
@@ -30,6 +31,7 @@
       : this.compiler = compiler,
         representationGenerator = new TypeRepresentationGenerator(compiler),
         classesNeedingRti = new Set<ClassElement>(),
+        methodsNeedingRti = new Set<Element>(),
         rtiDependencies = new Map<ClassElement, Set<ClassElement>>(),
         classesUsingTypeVariableExpression = new Set<ClassElement>();
 
@@ -77,7 +79,7 @@
         InterfaceType interface = type;
         do {
           for (DartType argument in interface.typeArguments) {
-            universe.isChecks.add(argument);
+            universe.registerIsCheck(argument, compiler);
           }
           interface = interface.element.supertype;
         } while (interface != null && !instantiatedTypes.contains(interface));
@@ -100,7 +102,7 @@
             InterfaceType instance = current.asInstanceOf(cls);
             if (instance == null) break;
             for (DartType argument in instance.typeArguments) {
-              universe.isChecks.add(argument);
+              universe.registerIsCheck(argument, compiler);
             }
             current = current.element.supertype;
           } while (current != null && !instantiatedTypes.contains(current));
@@ -155,18 +157,50 @@
     if (backend.jsArrayClass != null) {
       registerRtiDependency(backend.jsArrayClass, compiler.listClass);
     }
-    // Compute the set of all classes that need runtime type information.
+    // Compute the set of all classes and methods that need runtime type
+    // information.
     compiler.resolverWorld.isChecks.forEach((DartType type) {
       if (type.kind == TypeKind.INTERFACE) {
         InterfaceType itf = type;
         if (!itf.isRaw) {
           potentiallyAddForRti(itf.element);
         }
-      } else if (type.kind == TypeKind.TYPE_VARIABLE) {
-        TypeVariableElement variable = type.element;
-        potentiallyAddForRti(variable.enclosingElement);
+      } else {
+        ClassElement contextClass = Types.getClassContext(type);
+        if (contextClass != null) {
+          // [type] contains type variables (declared in [contextClass]) if
+          // [contextClass] is non-null. This handles checks against type
+          // variables and function types containing type variables.
+          potentiallyAddForRti(contextClass);
+        }
+        if (type.kind == TypeKind.FUNCTION) {
+          void analyzeMethod(Element method) {
+            DartType memberType = method.computeType(compiler);
+            ClassElement contextClass = Types.getClassContext(memberType);
+            if (contextClass != null &&
+                compiler.types.isPotentialSubtype(memberType, type)) {
+              potentiallyAddForRti(contextClass);
+              methodsNeedingRti.add(method);
+            }
+          }
+          compiler.resolverWorld.closurizedGenericMembers.forEach(
+              analyzeMethod);
+          compiler.resolverWorld.genericCallMethods.forEach(analyzeMethod);
+        }
       }
     });
+    if (compiler.enableTypeAssertions) {
+      void analyzeMethod(Element method) {
+        DartType memberType = method.computeType(compiler);
+        ClassElement contextClass = Types.getClassContext(memberType);
+        if (contextClass != null) {
+          potentiallyAddForRti(contextClass);
+          methodsNeedingRti.add(method);
+        }
+      }
+      compiler.resolverWorld.closurizedGenericMembers.forEach(analyzeMethod);
+      compiler.resolverWorld.genericCallMethods.forEach(analyzeMethod);
+    }
     // Add the classes that need RTI because they use a type variable as
     // expression.
     classesUsingTypeVariableExpression.forEach(potentiallyAddForRti);
@@ -210,12 +244,43 @@
   }
 
   void computeRequiredChecks() {
-    computeInstantiatedArguments(compiler.codegenWorld);
-    computeCheckedArguments(compiler.codegenWorld);
+    Set<DartType> isChecks = compiler.codegenWorld.isChecks;
+    bool hasFunctionTypeCheck =
+        isChecks.any((type) => identical(type.kind, TypeKind.FUNCTION));
+    Set<DartType> instantiatedTypesAndClosures = hasFunctionTypeCheck
+        ? computeInstantiatedTypesAndClosures(compiler.codegenWorld)
+        : compiler.codegenWorld.instantiatedTypes;
+    computeInstantiatedArguments(instantiatedTypesAndClosures, isChecks);
+    computeCheckedArguments(instantiatedTypesAndClosures, isChecks);
     cachedRequiredChecks =
         computeChecks(allInstantiatedArguments, checkedArguments);
   }
 
+  Set<DartType> computeInstantiatedTypesAndClosures(Universe universe) {
+    Set<DartType> instantiatedTypes =
+        new Set<DartType>.from(universe.instantiatedTypes);
+    for (DartType instantiatedType in universe.instantiatedTypes) {
+      if (instantiatedType.kind == TypeKind.INTERFACE) {
+        Member member =
+            instantiatedType.lookupMember(Compiler.CALL_OPERATOR_NAME);
+        if (member != null) {
+          instantiatedTypes.add(member.computeType(compiler));
+        }
+      }
+    }
+    for (FunctionElement element in universe.staticFunctionsNeedingGetter) {
+      instantiatedTypes.add(element.computeType(compiler));
+    }
+    // TODO(johnniwinther): We should get this information through the
+    // [neededClasses] computed in the emitter instead of storing it and pulling
+    // it from resolution, but currently it would introduce a cyclic dependency
+    // between [computeRequiredChecks] and [computeNeededClasses].
+    for (Element element in compiler.resolverWorld.closurizedMembers) {
+      instantiatedTypes.add(element.computeType(compiler));
+    }
+    return instantiatedTypes;
+  }
+
   /**
    * Collects all types used in type arguments of instantiated types.
    *
@@ -223,14 +288,26 @@
    * have a type check against this supertype that includes a check against
    * the type arguments.
    */
-  void computeInstantiatedArguments(Universe universe) {
+  void computeInstantiatedArguments(Set<DartType> instantiatedTypes,
+                                    Set<DartType> isChecks) {
     ArgumentCollector superCollector = new ArgumentCollector(backend);
     ArgumentCollector directCollector = new ArgumentCollector(backend);
-    for (DartType type in universe.instantiatedTypes) {
+    FunctionArgumentCollector functionArgumentCollector =
+        new FunctionArgumentCollector(backend);
+
+    // We need to add classes occuring in function type arguments, like for
+    // instance 'I' for [: o is C<f> :] where f is [: typedef I f(); :].
+    for (DartType type in isChecks) {
+      functionArgumentCollector.collect(type);
+    }
+
+    for (DartType type in instantiatedTypes) {
       directCollector.collect(type);
-      ClassElement cls = type.element;
-      for (DartType supertype in cls.allSupertypes) {
-        superCollector.collect(supertype);
+      if (type.kind == TypeKind.INTERFACE) {
+        ClassElement cls = type.element;
+        for (DartType supertype in cls.allSupertypes) {
+          superCollector.collect(supertype);
+        }
       }
     }
     for (ClassElement cls in superCollector.classes.toList()) {
@@ -238,18 +315,33 @@
         superCollector.collect(supertype);
       }
     }
-    directlyInstantiatedArguments = directCollector.classes;
+
+    directlyInstantiatedArguments =
+        directCollector.classes..addAll(functionArgumentCollector.classes);
     allInstantiatedArguments =
         superCollector.classes..addAll(directlyInstantiatedArguments);
   }
 
   /// Collects all type arguments used in is-checks.
-  void computeCheckedArguments(Universe universe) {
+  void computeCheckedArguments(Set<DartType> instantiatedTypes,
+                               Set<DartType> isChecks) {
     ArgumentCollector collector = new ArgumentCollector(backend);
-    for (DartType type in universe.isChecks) {
+    FunctionArgumentCollector functionArgumentCollector =
+        new FunctionArgumentCollector(backend);
+
+    // We need to add types occuring in function type arguments, like for
+    // instance 'J' for [: (J j) {} is f :] where f is
+    // [: typedef void f(I i); :] and 'J' is a subtype of 'I'.
+    for (DartType type in instantiatedTypes) {
+      functionArgumentCollector.collect(type);
+    }
+
+    for (DartType type in isChecks) {
       collector.collect(type);
     }
-    checkedArguments = collector.classes;
+
+    checkedArguments =
+        collector.classes..addAll(functionArgumentCollector.classes);
   }
 
   Set<ClassElement> getClassesUsedInSubstitutions(JavaScriptBackend backend,
@@ -392,7 +484,42 @@
     return '[$code]';
   }
 
-  String getTypeRepresentation(DartType type, void onVariable(variable)) {
+  String getTypeEncoding(DartType type,
+                         {bool alwaysGenerateFunction: false}) {
+    ClassElement contextClass = Types.getClassContext(type);
+    String onVariable(TypeVariableType v) {
+      return v.toString();
+    };
+    String encoding = _getTypeRepresentation(type, onVariable);
+    if (contextClass == null && !alwaysGenerateFunction) {
+      return encoding;
+    } else {
+      String parameters = contextClass != null
+          ? contextClass.typeVariables.toList().join(', ')
+          : '';
+      return 'function ($parameters) { return $encoding; }';
+    }
+  }
+
+  String getSignatureEncoding(DartType type, String generateThis()) {
+    ClassElement contextClass = Types.getClassContext(type);
+    String encoding = getTypeEncoding(type, alwaysGenerateFunction: true);
+    if (contextClass != null) {
+      String this_ = generateThis();
+      JavaScriptBackend backend = compiler.backend;
+      String computeSignature =
+          backend.namer.getName(backend.getComputeSignature());
+      String contextName = backend.namer.getName(contextClass);
+      return 'function () {'
+             ' return ${backend.namer.GLOBAL_OBJECT}.'
+                  '$computeSignature($encoding, $this_, "$contextName"); '
+             '}';
+    } else {
+      return encoding;
+    }
+  }
+
+  String getTypeRepresentation(DartType type, VariableSubstitution onVariable) {
     // Create a type representation.  For type variables call the original
     // callback for side effects and return a template placeholder.
     return _getTypeRepresentation(type, (variable) {
@@ -432,6 +559,9 @@
   OnVariableCallback onVariable;
   StringBuffer builder;
 
+  JavaScriptBackend get backend => compiler.backend;
+  Namer get namer => backend.namer;
+
   TypeRepresentationGenerator(Compiler this.compiler);
 
   /**
@@ -449,8 +579,6 @@
   }
 
   String getJsName(Element element) {
-    JavaScriptBackend backend = compiler.backend;
-    Namer namer = backend.namer;
     return namer.isolateAccess(backend.getImplementationClass(element));
   }
 
@@ -491,25 +619,26 @@
   }
 
   visitFunctionType(FunctionType type, _) {
-    builder.write('{func: true');
+    builder.write('{${namer.functionTypeTag()}:'
+                  ' "${namer.getFunctionTypeName(type)}"');
     if (type.returnType.isVoid) {
-      builder.write(', retvoid: true');
+      builder.write(', ${namer.functionTypeVoidReturnTag()}: true');
     } else if (!type.returnType.isDynamic) {
-      builder.write(', ret: ');
+      builder.write(', ${namer.functionTypeReturnTypeTag()}: ');
       visit(type.returnType);
     }
     if (!type.parameterTypes.isEmpty) {
-      builder.write(', args: [');
+      builder.write(', ${namer.functionTypeRequiredParametersTag()}: [');
       visitList(type.parameterTypes);
       builder.write(']');
     }
     if (!type.optionalParameterTypes.isEmpty) {
-      builder.write(', opt: [');
+      builder.write(', ${namer.functionTypeOptionalParametersTag()}: [');
       visitList(type.optionalParameterTypes);
       builder.write(']');
     }
     if (!type.namedParameterTypes.isEmpty) {
-      builder.write(', named: {');
+      builder.write(', ${namer.functionTypeNamedParametersTag()}: {');
       bool first = true;
       Link<SourceString> names = type.namedParameters;
       Link<DartType> types = type.namedParameterTypes;
@@ -529,8 +658,13 @@
     builder.write('}');
   }
 
+  visitMalformedType(MalformedType type, _) {
+    // Treat malformed types as dynamic at runtime.
+    builder.write('null');
+  }
+
   visitType(DartType type, _) {
-    compiler.internalError('Unexpected type: $type');
+    compiler.internalError('Unexpected type: $type (${type.kind})');
   }
 }
 
@@ -589,6 +723,10 @@
     // Do not collect [:dynamic:].
   }
 
+  visitTypedefType(TypedefType type, bool isTypeArgument) {
+    type.unalias(backend.compiler).accept(this, isTypeArgument);
+  }
+
   visitInterfaceType(InterfaceType type, bool isTypeArgument) {
     if (isTypeArgument) {
       classes.add(backend.getImplementationClass(type.element));
@@ -601,6 +739,48 @@
   }
 }
 
+class FunctionArgumentCollector extends DartTypeVisitor {
+  final JavaScriptBackend backend;
+  final Set<ClassElement> classes = new Set<ClassElement>();
+
+  FunctionArgumentCollector(this.backend);
+
+  collect(DartType type) {
+    type.accept(this, false);
+  }
+
+  /// Collect all types in the list as if they were arguments of an
+  /// InterfaceType.
+  collectAll(Link<DartType> types) {
+    for (Link<DartType> link = types; !link.isEmpty; link = link.tail) {
+      link.head.accept(this, true);
+    }
+  }
+
+  visitType(DartType type, _) {
+    // Do nothing.
+  }
+
+  visitDynamicType(DynamicType type, _) {
+    // Do not collect [:dynamic:].
+  }
+
+  visitTypedefType(TypedefType type, bool inFunctionType) {
+    type.unalias(backend.compiler).accept(this, inFunctionType);
+  }
+
+  visitInterfaceType(InterfaceType type, bool inFunctionType) {
+    if (inFunctionType) {
+      classes.add(backend.getImplementationClass(type.element));
+    }
+    type.visitChildren(this, inFunctionType);
+  }
+
+  visitFunctionType(FunctionType type, _) {
+    type.visitChildren(this, true);
+  }
+}
+
 /**
  * Representation of the substitution of type arguments
  * when going from the type of a class to one of its supertypes.
@@ -632,7 +812,7 @@
       String formals = parameters.toList().map(variableName).join(', ');
       return 'function ($formals) { return $code; }';
     } else if (ensureIsFunction) {
-      return 'function() { return $code; }';
+      return 'function () { return $code; }';
     } else {
       return code;
     }
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index df00f77..c6f20a0 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -25,9 +25,6 @@
 
   /// The type Object, but no subtypes:
   static const JsObject = const SpecialType._('=Object');
-
-  /// The specific implementation of List that is JavaScript Array:
-  static const JsArray = const SpecialType._('=List');
 }
 
 
@@ -331,9 +328,7 @@
       if (matchedTypeConstraints.contains(type)) continue;
       matchedTypeConstraints.add(type);
       if (type is SpecialType) {
-        if (type == SpecialType.JsArray) {
-          world.registerInstantiatedClass(compiler.listClass, elements);
-        } else if (type == SpecialType.JsObject) {
+        if (type == SpecialType.JsObject) {
           world.registerInstantiatedClass(compiler.objectClass, elements);
         }
         continue;
@@ -352,6 +347,9 @@
           world.registerInstantiatedClass(compiler.nullClass, elements);
         } else if (type.element == compiler.boolClass) {
           world.registerInstantiatedClass(compiler.boolClass, elements);
+        } else if (compiler.types.isSubtype(
+                      type, compiler.backend.listImplementation.rawType)) {
+          world.registerInstantiatedClass(type.element, elements);
         }
       }
       assert(type is DartType);
@@ -634,7 +632,6 @@
     //
     //  'Type1|Type2'.  A union type.
     //  '=Object'.      A JavaScript Object, no subtype.
-    //  '=List'.        A JavaScript Array, no subtype.
 
     var argNodes = jsCall.arguments;
     if (argNodes.isEmpty) {
@@ -816,7 +813,6 @@
   static _parseType(String typeString, Compiler compiler,
       lookup(name), locationNodeOrElement) {
     if (typeString == '=Object') return SpecialType.JsObject;
-    if (typeString == '=List') return SpecialType.JsArray;
     if (typeString == 'dynamic') {
       return  compiler.dynamicClass.computeType(compiler);
     }
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 95f6edf..4f619ce 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -1901,6 +1901,12 @@
       }
       parameterNodes = parameterNodes.tail;
     });
+    if (inCheckContext) {
+      functionParameters.forEachParameter((Element element) {
+        compiler.enqueuer.resolution.registerIsCheck(
+            element.computeType(compiler), mapping);
+      });
+    }
   }
 
   visitCascade(Cascade node) {
@@ -1998,6 +2004,7 @@
     scope = oldScope;
     enclosingElement = previousEnclosingElement;
 
+    world.registerClosurizedMember(function, mapping);
     world.registerInstantiatedClass(compiler.functionClass, mapping);
   }
 
@@ -2076,7 +2083,7 @@
         // We still need to register the invocation, because we might
         // call [:super.noSuchMethod:] which calls
         // [JSInvocationMirror._invokeOn].
-        world.registerDynamicInvocation(selector.name, selector);
+        world.registerDynamicInvocation(selector);
         compiler.backend.registerSuperNoSuchMethod(mapping);
       }
     } else if (Elements.isUnresolved(resolvedReceiver)) {
@@ -2104,7 +2111,7 @@
         // [resolveSend] to select better warning messages for getters and
         // setters.
         MessageKind kind = (target == null)
-            ? MessageKind.METHOD_NOT_FOUND
+            ? MessageKind.MEMBER_NOT_FOUND
             : MessageKind.MEMBER_NOT_STATIC;
         return warnAndCreateErroneousElement(node, name, kind,
                                              {'className': receiverClass.name,
@@ -2250,6 +2257,10 @@
         assert(enclosingElement.getEnclosingClass() == cls);
         compiler.backend.registerClassUsingVariableExpression(cls);
         compiler.backend.registerTypeVariableExpression(mapping);
+        // Set the type of the node to [Type] to mark this send as a
+        // type variable expression.
+        mapping.setType(node, compiler.typeClass.computeType(compiler));
+        world.registerInstantiatedClass(compiler.typeClass, mapping);
       } else if (target.impliesType() && !sendIsMemberAccess) {
         // Set the type of the node to [Type] to mark this send as a
         // type literal.
@@ -2262,7 +2273,8 @@
     if (node.isOperator) {
       String operatorString = node.selector.asOperator().source.stringValue;
       if (operatorString == 'is') {
-        DartType type = resolveTypeRequired(node.typeAnnotationFromIsCheck);
+        DartType type =
+            resolveTypeRequired(node.typeAnnotationFromIsCheckOrCast);
         if (type != null) {
           compiler.enqueuer.resolution.registerIsCheck(type, mapping);
         }
@@ -2302,7 +2314,7 @@
         // we need to register that fact that we may be calling a closure
         // with the same arguments.
         Selector call = new Selector.callClosureFrom(selector);
-        world.registerDynamicInvocation(call.name, call);
+        world.registerDynamicInvocation(call);
       } else if (target.impliesType()) {
         // We call 'call()' on a Type instance returned from the reference to a
         // class or typedef literal. We do not need to register this call as a
@@ -2412,7 +2424,7 @@
       // the ++ and -- ones.  Also, if op= form is used, include op itself.
       void registerBinaryOperator(SourceString name) {
         Selector binop = new Selector.binaryOperator(name);
-        world.registerDynamicInvocation(binop.name, binop);
+        world.registerDynamicInvocation(binop);
         mapping.setOperatorSelectorInComplexSendSet(node, binop);
       }
       if (identical(source, '++')) {
@@ -2431,11 +2443,11 @@
   void registerSend(Selector selector, Element target) {
     if (target == null || target.isInstanceMember()) {
       if (selector.isGetter()) {
-        world.registerDynamicGetter(selector.name, selector);
+        world.registerDynamicGetter(selector);
       } else if (selector.isSetter()) {
-        world.registerDynamicSetter(selector.name, selector);
+        world.registerDynamicSetter(selector);
       } else {
-        world.registerDynamicInvocation(selector.name, selector);
+        world.registerDynamicInvocation(selector);
       }
     } else if (Elements.isStaticOrTopLevel(target)) {
       // TODO(kasperl): It seems like we're not supposed to register
@@ -2615,6 +2627,10 @@
     world.registerStaticUse(constructor.declaration);
     ClassElement cls = constructor.getEnclosingClass();
     InterfaceType type = mapping.getType(node);
+    if (node.isConst() && type.containsTypeVariables) {
+      compiler.reportErrorCode(node.send.selector,
+                               MessageKind.TYPE_VARIABLE_IN_CONSTANT);
+    }
     world.registerInstantiatedType(type, mapping);
     if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) {
       world.registerFactoryWithTypeArguments(mapping);
@@ -2723,6 +2739,10 @@
     }
     DartType listType;
     if (typeArgument != null) {
+      if (node.isConst() && typeArgument.containsTypeVariables) {
+        compiler.reportErrorCode(arguments.nodes.head,
+            MessageKind.TYPE_VARIABLE_IN_CONSTANT);
+      }
       listType = new InterfaceType(compiler.listClass,
                                    new Link<DartType>.fromList([typeArgument]));
     } else {
@@ -2810,20 +2830,17 @@
 
   registerImplicitInvocation(SourceString name, int arity) {
     Selector selector = new Selector.call(name, null, arity);
-    world.registerDynamicInvocation(name, selector);
+    world.registerDynamicInvocation(selector);
   }
 
   visitForIn(ForIn node) {
     LibraryElement library = enclosingElement.getLibrary();
     mapping.setIteratorSelector(node, compiler.iteratorSelector);
-    world.registerDynamicGetter(compiler.iteratorSelector.name,
-                                compiler.iteratorSelector);
+    world.registerDynamicGetter(compiler.iteratorSelector);
     mapping.setCurrentSelector(node, compiler.currentSelector);
-    world.registerDynamicGetter(compiler.currentSelector.name,
-                                compiler.currentSelector);
+    world.registerDynamicGetter(compiler.currentSelector);
     mapping.setMoveNextSelector(node, compiler.moveNextSelector);
-    world.registerDynamicInvocation(compiler.moveNextSelector.name,
-                                    compiler.moveNextSelector);
+    world.registerDynamicInvocation(compiler.moveNextSelector);
 
     visit(node.expression);
     Scope blockScope = new BlockScope(scope);
@@ -2938,6 +2955,10 @@
       compiler.mapClass.computeType(compiler);
       mapType = compiler.mapClass.rawType;
     }
+    if (node.isConst() && mapType.containsTypeVariables) {
+      compiler.reportErrorCode(arguments,
+          MessageKind.TYPE_VARIABLE_IN_CONSTANT);
+    }
     mapping.setType(node, mapType);
     world.registerInstantiatedClass(compiler.mapClass, mapping);
     if (node.isConst()) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 75d6443..3b3c999 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -53,7 +53,6 @@
       assert(graph.isValid());
       if (!identical(kind, ElementKind.FIELD)) {
         FunctionElement function = element;
-        graph.calledInLoop = compiler.world.isCalledInLoop(function);
         FunctionSignature signature = function.computeSignature(compiler);
         signature.forEachOptionalParameter((Element parameter) {
           // This ensures the default value will be computed.
@@ -932,10 +931,14 @@
 
   static const MAX_INLINING_DEPTH = 3;
   static const MAX_INLINING_NODES = 46;
+
   List<InliningState> inliningStack;
+
   Element returnElement;
   DartType returnType;
+
   bool inTryStatement = false;
+  int loopNesting = 0;
 
   HBasicBlock get current => _current;
   void set current(c) {
@@ -1002,6 +1005,7 @@
    */
   HGraph buildMethod(FunctionElement functionElement) {
     assert(invariant(functionElement, functionElement.isImplementation));
+    graph.calledInLoop = compiler.world.isCalledInLoop(functionElement);
     FunctionExpression function = functionElement.parseNode(compiler);
     assert(function != null);
     assert(!function.modifiers.isExternal());
@@ -1171,7 +1175,7 @@
 
     ClassElement enclosing = function.getEnclosingClass();
     if ((function.isConstructor() || function.isGenerativeConstructorBody())
-        && backend.needsRti(enclosing)) {
+        && backend.classNeedsRti(enclosing)) {
       enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
         HInstruction argument = compiledArguments[argumentIndex++];
         newLocalsHandler.updateLocal(typeVariable.element, argument);
@@ -1222,7 +1226,10 @@
     // connected-component of the deferred library.
     if (compiler.deferredLoadTask.isDeferred(element)) return false;
     if (compiler.disableInlining) return false;
-    if (inliningStack.length > MAX_INLINING_DEPTH) return false;
+
+    if (loopNesting == 0 && !graph.calledInLoop) return false;
+    int maxDepth = (loopNesting > 0) ? MAX_INLINING_DEPTH : 1;
+    if (inliningStack.length >= maxDepth) return false;
 
     // Ensure that [element] is an implementation element.
     element = element.implementation;
@@ -1242,6 +1249,15 @@
       }
     }
 
+    // Don't inline if the return type was inferred to be non-null empty. This
+    // means that the function always throws an exception.
+    TypeMask returnType =
+        compiler.typesTask.getGuaranteedReturnTypeOfElement(element);
+    if (returnType != null && returnType.isEmpty && !returnType.isNullable) {
+      isReachable = false;
+      return false;
+    }
+
     FunctionExpression functionExpression = function.parseNode(compiler);
     TreeElements newElements =
         compiler.enqueuer.resolution.getCachedElements(function);
@@ -1327,7 +1343,7 @@
       }
 
       ClassElement superclass = constructor.getEnclosingClass();
-      if (backend.needsRti(superclass)) {
+      if (backend.classNeedsRti(superclass)) {
         // If [superclass] needs RTI, we have to give a value to its
         // type parameters. Those values are in the [supertype]
         // declaration of [subclass].
@@ -1574,7 +1590,7 @@
     add(newObject);
 
     // Create the runtime type information, if needed.
-    if (backend.needsRti(classElement)) {
+    if (backend.classNeedsRti(classElement)) {
       List<HInstruction> rtiInputs = <HInstruction>[];
       classElement.typeVariables.forEach((TypeVariableType typeVariable) {
         rtiInputs.add(localsHandler.readLocal(typeVariable.element));
@@ -1620,7 +1636,7 @@
       });
 
       ClassElement currentClass = constructor.getEnclosingClass();
-      if (backend.needsRti(currentClass)) {
+      if (backend.classNeedsRti(currentClass)) {
         // If [currentClass] needs RTI, we add the type variables as
         // parameters of the generative constructor body.
         currentClass.typeVariables.forEach((DartType argument) {
@@ -1724,7 +1740,7 @@
     // may contain references to type variables.
     var enclosing = element.enclosingElement;
     if ((element.isConstructor() || element.isGenerativeConstructorBody())
-        && backend.needsRti(enclosing)) {
+        && backend.classNeedsRti(enclosing)) {
       enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
         HParameterValue param = addParameter(typeVariable.element);
         localsHandler.directLocals[typeVariable.element] = param;
@@ -1773,6 +1789,7 @@
                                    DartType type,
                                    int kind) {
     if (type == null) return original;
+    type = type.unalias(compiler);
     if (type.kind == TypeKind.INTERFACE && !type.isMalformed && !type.isRaw) {
      HType subtype = new HType.subtype(type, compiler);
      HInstruction representations = buildTypeArgumentRepresentations(type);
@@ -1784,6 +1801,24 @@
       HInstruction typeVariable = addTypeVariableReference(type);
       return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
           original, typeVariable);
+    } else if (type.kind == TypeKind.FUNCTION) {
+      HType subtype = original.instructionType;
+      if (type.containsTypeVariables) {
+        bool contextIsTypeArguments = false;
+        HInstruction context;
+        if (currentElement.isInstanceMember()) {
+          context = localsHandler.readThis();
+        } else {
+          ClassElement contextClass = Types.getClassContext(type);
+          context = buildTypeVariableList(contextClass);
+          add(context);
+          contextIsTypeArguments = true;
+        }
+        return new HTypeConversion.withContext(type, kind, subtype,
+            original, context, contextIsTypeArguments: contextIsTypeArguments);
+      } else {
+        return new HTypeConversion(type, kind, subtype, original);
+      }
     } else {
       return original.convertType(compiler, type, kind);
     }
@@ -1794,6 +1829,7 @@
     if (!compiler.enableTypeAssertions) return original;
     HInstruction other = buildTypeConversion(original, type, kind);
     if (other != original) add(other);
+    compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree);
     return other;
   }
 
@@ -2070,6 +2106,7 @@
           new SubExpression(initializerBlock, current);
     }
 
+    loopNesting++;
     JumpHandler jumpHandler = beginLoopHeader(loop);
     HLoopInformation loopInfo = current.loopInformation;
     HBasicBlock conditionBlock = current;
@@ -2229,6 +2266,7 @@
       }
     }
     jumpHandler.close();
+    loopNesting--;
   }
 
   visitFor(For node) {
@@ -2283,6 +2321,7 @@
     assert(isReachable);
     LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
     localsHandler.startLoop(node);
+    loopNesting++;
     JumpHandler jumpHandler = beginLoopHeader(node);
     HLoopInformation loopInfo = current.loopInformation;
     HBasicBlock loopEntryBlock = current;
@@ -2408,6 +2447,7 @@
       }
     }
     jumpHandler.close();
+    loopNesting--;
   }
 
   visitFunctionExpression(FunctionExpression node) {
@@ -2439,6 +2479,12 @@
         compiler.functionClass.computeType(compiler),
         compiler);
     push(new HForeignNew(closureClassElement, type, capturedVariables));
+
+    Element methodElement = nestedClosureData.closureElement;
+    if (compiler.backend.methodNeedsRti(methodElement)) {
+      compiler.backend.registerGenericClosure(
+          methodElement, compiler.enqueuer.codegen, work.resolutionTree);
+    }
   }
 
   visitFunctionDeclaration(FunctionDeclaration node) {
@@ -2548,7 +2594,7 @@
 
   String getTargetName(ErroneousElement error, [String prefix]) {
     String result = error.name.slowToString();
-    if (?prefix) {
+    if (prefix != null) {
       result = '$prefix $result';
     }
     return result;
@@ -2722,7 +2768,7 @@
     }
   }
 
-  visitOperatorSend(node) {
+  visitOperatorSend(Send node) {
     Operator op = node.selector;
     if (const SourceString("[]") == op.source) {
       visitDynamicSend(node);
@@ -2758,7 +2804,8 @@
     visit(node.receiver);
     HInstruction expression = pop();
     bool isNot = node.isIsNotCheck;
-    DartType type = elements.getType(node.typeAnnotationFromIsCheck);
+    DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
+    type = type.unalias(compiler);
     if (type.isMalformed) {
       String reasons = Types.fetchReasonsFromMalformedType(type);
       if (compiler.enableTypeAssertions) {
@@ -2776,8 +2823,57 @@
     }
   }
 
+  HLiteralList buildTypeVariableList(ClassElement contextClass) {
+    List<HInstruction> inputs = <HInstruction>[];
+    for (Link<DartType> link = contextClass.typeVariables;
+        !link.isEmpty;
+        link = link.tail) {
+      inputs.add(addTypeVariableReference(link.head));
+    }
+    return buildLiteralList(inputs);
+  }
+
   HInstruction buildIsNode(Node node, DartType type, HInstruction expression) {
-    if (type.kind == TypeKind.TYPE_VARIABLE) {
+    type = type.unalias(compiler);
+    if (type.kind == TypeKind.FUNCTION) {
+      Element checkFunctionSubtype = backend.getCheckFunctionSubtype();
+
+      HInstruction signatureName = graph.addConstantString(
+          new DartString.literal(backend.namer.getFunctionTypeName(type)),
+          node, compiler);
+
+      HInstruction contextName;
+      HInstruction context;
+      HInstruction typeArguments;
+      if (type.containsTypeVariables) {
+        ClassElement contextClass = Types.getClassContext(type);
+        contextName = graph.addConstantString(
+            new DartString.literal(backend.namer.getName(contextClass)),
+            node, compiler);
+        if (currentElement.isInstanceMember()) {
+          context = localsHandler.readThis();
+          typeArguments = graph.addConstantNull(compiler);
+        } else {
+          context = graph.addConstantNull(compiler);
+          typeArguments = buildTypeVariableList(contextClass);
+          add(typeArguments);
+        }
+      } else {
+        contextName = graph.addConstantNull(compiler);
+        context = graph.addConstantNull(compiler);
+        typeArguments = graph.addConstantNull(compiler);
+      }
+
+      List<HInstruction> inputs = <HInstruction>[expression,
+                                                 signatureName,
+                                                 contextName,
+                                                 context,
+                                                 typeArguments];
+      pushInvokeStatic(node, checkFunctionSubtype, inputs, HType.BOOLEAN);
+      HInstruction call = pop();
+      return new HIs(type, <HInstruction>[expression, call],
+          HIs.COMPOUND_CHECK);
+    } else if (type.kind == TypeKind.TYPE_VARIABLE) {
       HInstruction runtimeType = addTypeVariableReference(type);
       Element helper = backend.getCheckSubtypeOfRuntimeType();
       List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
@@ -2975,6 +3071,18 @@
     }
   }
 
+  void handleForeignJsSetupObject(Send node) {
+    if (!node.arguments.isEmpty) {
+      compiler.cancel(
+          'Too many arguments to JS_GLOBAL_OBJECT', node: node);
+    }
+
+    String name = backend.namer.GLOBAL_OBJECT;
+    push(new HForeign(new js.LiteralString(name),
+                      HType.UNKNOWN,
+                      <HInstruction>[]));
+  }
+
   void handleForeignJsCallInIsolate(Send node) {
     Link<Node> link = node.arguments;
     if (!compiler.hasIsolateSupport()) {
@@ -3086,6 +3194,8 @@
       handleForeignJs(node);
     } else if (name == const SourceString('JS_CURRENT_ISOLATE_CONTEXT')) {
       handleForeignJsCurrentIsolateContext(node);
+    } else if (name == const SourceString('JS_GLOBAL_OBJECT')) {
+      handleForeignJsSetupObject(node);
     } else if (name == const SourceString('JS_CALL_IN_ISOLATE')) {
       handleForeignJsCallInIsolate(node);
     } else if (name == const SourceString('DART_CLOSURE_TO_JS')) {
@@ -3101,8 +3211,33 @@
     } else if (name == const SourceString('JS_OBJECT_CLASS_NAME')) {
       String name = backend.namer.getRuntimeTypeName(compiler.objectClass);
       stack.add(addConstantString(node, name));
+    } else if (name == const SourceString('JS_FUNCTION_CLASS_NAME')) {
+      String name = backend.namer.getRuntimeTypeName(compiler.functionClass);
+      stack.add(addConstantString(node, name));
     } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) {
       stack.add(addConstantString(node, backend.namer.operatorAsPrefix()));
+    } else if (name == const SourceString('JS_SIGNATURE_NAME')) {
+      stack.add(addConstantString(node, backend.namer.operatorSignature()));
+    } else if (name == const SourceString('JS_FUNCTION_TYPE_TAG')) {
+      stack.add(addConstantString(node, backend.namer.functionTypeTag()));
+    } else if (name == const SourceString('JS_FUNCTION_TYPE_VOID_RETURN_TAG')) {
+      stack.add(addConstantString(node,
+                                  backend.namer.functionTypeVoidReturnTag()));
+    } else if (name == const SourceString('JS_FUNCTION_TYPE_RETURN_TYPE_TAG')) {
+      stack.add(addConstantString(node,
+                                  backend.namer.functionTypeReturnTypeTag()));
+    } else if (name ==
+               const SourceString('JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG')) {
+      stack.add(addConstantString(node,
+          backend.namer.functionTypeRequiredParametersTag()));
+    } else if (name ==
+               const SourceString('JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG')) {
+      stack.add(addConstantString(node,
+          backend.namer.functionTypeOptionalParametersTag()));
+    } else if (name ==
+               const SourceString('JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG')) {
+      stack.add(addConstantString(node,
+          backend.namer.functionTypeNamedParametersTag()));
     } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) {
       handleForeignDartObjectJsConstructorFunction(node);
     } else if (name == const SourceString('JS_IS_INDEXABLE_FIELD_NAME')) {
@@ -3219,17 +3354,14 @@
                                 TypeVariableElement variable) {
     assert(currentElement.isInstanceMember());
     int index = RuntimeTypes.getTypeVariableIndex(variable);
-    String substitutionNameString = backend.namer.substitutionName(cls);
+    String substitutionNameString = backend.namer.getName(cls);
     HInstruction substitutionName = graph.addConstantString(
         new LiteralDartString(substitutionNameString), null, compiler);
     HInstruction target = localsHandler.readThis();
-    HInstruction substitution = createForeign('#[#]', HType.UNKNOWN,
-        <HInstruction>[target, substitutionName]);
-    add(substitution);
     pushInvokeStatic(null,
                      backend.getGetRuntimeTypeArgument(),
                      [target,
-                      substitution,
+                      substitutionName,
                       graph.addConstantInt(index, compiler)],
                       HType.UNKNOWN);
     return pop();
@@ -3246,13 +3378,29 @@
       member = closureClass.methodElement;
       member = member.getOutermostEnclosingMemberOrTopLevel();
     }
-    if (isClosure && member.isFactoryConstructor()) {
-      // The type variable is used from a closure in a factory constructor.  The
-      // value of the type argument is stored as a local on the closure itself.
-      return localsHandler.readLocal(type.element);
-    } else if (member.isConstructor() ||
-               member.isGenerativeConstructorBody() ||
-               member.isField()) {
+    bool isInConstructorContext = member.isConstructor() ||
+        member.isGenerativeConstructorBody() ||
+        member.isField();
+    if (isClosure) {
+      if (member.isFactoryConstructor()) {
+        // The type variable is used from a closure in a factory constructor.
+        // The value of the type argument is stored as a local on the closure
+        // itself.
+        return localsHandler.readLocal(type.element);
+      } else if (member.isFunction() ||
+          member.isGetter() ||
+          member.isSetter() ||
+          member.isConstructor() ||
+          member.isGenerativeConstructorBody()) {
+        // The type variable is stored on the "enclosing object" and needs to be
+        // accessed using the this-reference in the closure.
+        return readTypeVariable(member.getEnclosingClass(), type.element);
+      } else {
+        assert(member.isField());
+        // The type variable is stored in a parameter of the method.
+        return localsHandler.readLocal(type.element);
+      }
+    } else if (isInConstructorContext) {
       // The type variable is stored in a parameter of the method.
       return localsHandler.readLocal(type.element);
     } else if (member.isInstanceMember()) {
@@ -3295,7 +3443,7 @@
   void handleListConstructor(InterfaceType type,
                              Node currentNode,
                              HInstruction newObject) {
-    if (!backend.needsRti(type.element)) return;
+    if (!backend.classNeedsRti(type.element)) return;
     if (!type.isRaw) {
       List<HInstruction> inputs = <HInstruction>[];
       type.typeArguments.forEach((DartType argument) {
@@ -3308,7 +3456,7 @@
   void callSetRuntimeTypeInfo(ClassElement element,
                               List<HInstruction> rtiInputs,
                               HInstruction newObject) {
-    if (!backend.needsRti(element) || element.typeVariables.isEmpty) {
+    if (!backend.classNeedsRti(element) || element.typeVariables.isEmpty) {
       return;
     }
 
@@ -3338,23 +3486,25 @@
     bool isListConstructor = false;
     computeType(element) {
       Element originalElement = elements[send];
-      if (Elements.isFixedListConstructorCall(
-              originalElement, send, compiler)) {
+      if (Elements.isFixedListConstructorCall(originalElement, send, compiler)
+          || Elements.isFilledListConstructorCall(
+                  originalElement, send, compiler)) {
         isListConstructor = true;
         HType inferred =
-            new HType.inferredForNode(currentElement, node, compiler);
+            new HType.inferredForNode(currentElement, send, compiler);
         return inferred.isUnknown() ? backend.fixedArrayType : inferred;
       } else if (Elements.isGrowableListConstructorCall(
                     originalElement, send, compiler)) {
         isListConstructor = true;
         HType inferred =
-            new HType.inferredForNode(currentElement, node, compiler);
+            new HType.inferredForNode(currentElement, send, compiler);
         return inferred.isUnknown() ? backend.extendableArrayType : inferred;
       } else if (element.isGenerativeConstructor()) {
         ClassElement cls = element.getEnclosingClass();
         return new HType.nonNullExact(cls.thisType, compiler);
       } else {
-        return new HType.inferredTypeForElement(originalElement, compiler);
+        return new HType.inferredReturnTypeForElement(
+            originalElement, compiler);
       }
     }
 
@@ -3385,18 +3535,7 @@
     bool isRedirected = functionElement.isRedirectingFactory;
     DartType expectedType = type;
     if (isRedirected) {
-      FunctionExpression functionNode = functionElement.parseNode(compiler);
-      if (functionNode.isRedirectingFactory) {
-        // Lookup the type used in the redirection.
-        Return redirectionNode = functionNode.body;
-        TreeElements treeElements =
-            compiler.enqueuer.resolution.getCachedElements(
-                functionElement.declaration);
-        ClassElement targetClass = functionElement.getEnclosingClass();
-        type = treeElements.getType(redirectionNode.expression)
-            .subst(type.typeArguments, targetClass.typeVariables);
-      }
-      functionElement = functionElement.redirectionTarget;
+      type = functionElement.computeTargetType(compiler, type);
     }
 
     var inputs = <HInstruction>[];
@@ -3415,7 +3554,7 @@
       generateAbstractClassInstantiationError(send, cls.name.slowToString());
       return;
     }
-    if (backend.needsRti(cls)) {
+    if (backend.classNeedsRti(cls)) {
       Link<DartType> typeVariable = cls.typeVariables;
       type.typeArguments.forEach((DartType argument) {
         inputs.add(analyzeTypeArgument(argument, send));
@@ -3440,7 +3579,7 @@
     // not know about the type argument. Therefore we special case
     // this constructor to have the setRuntimeTypeInfo called where
     // the 'new' is done.
-    if (isListConstructor && backend.needsRti(compiler.listClass)) {
+    if (isListConstructor && backend.classNeedsRti(compiler.listClass)) {
       handleListConstructor(type, send, newInstance);
     }
 
@@ -3651,7 +3790,6 @@
         generateRuntimeError(node.send, message.toString());
       }
     } else if (node.isConst()) {
-      // TODO(karlklose): add type representation
       ConstantHandler handler = compiler.constantHandler;
       Constant constant = handler.compileNodeWithDefinitions(node, elements);
       stack.add(graph.addConstant(constant, compiler));
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index b4f0d92..ef11642 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -1550,12 +1550,6 @@
     return receiverType.refine(selector, compiler);
   }
 
-  void registerInvoke(HInvokeDynamic node, Selector selector) {
-    if (node.isInterceptedCall) {
-      backend.addInterceptedSelector(selector);
-    }
-  }
-
   void registerMethodInvoke(HInvokeDynamic node) {
     Selector selector = getOptimizedSelectorFor(node, node.selector);
 
@@ -1568,35 +1562,22 @@
       // may know something about the types of closures that need
       // the specific closure call method.
       Selector call = new Selector.callClosureFrom(selector);
-      world.registerDynamicInvocation(call.name, call);
+      world.registerDynamicInvocation(call);
     }
-
-    if (target != null) {
-      // If we know we're calling a specific method, register that
-      // method only.
-      world.registerDynamicInvocationOf(target, selector);
-    } else {
-      SourceString name = node.selector.name;
-      world.registerDynamicInvocation(name, selector);
-    }
-    registerInvoke(node, selector);
+    world.registerDynamicInvocation(selector);
   }
 
   void registerSetter(HInvokeDynamic node) {
     Selector selector = getOptimizedSelectorFor(node, node.selector);
-    world.registerDynamicSetter(selector.name, selector);
+    world.registerDynamicSetter(selector);
     HType valueType = node.isInterceptedCall
         ? node.inputs[2].instructionType
         : node.inputs[1].instructionType;
-    registerInvoke(node, selector);
   }
 
   void registerGetter(HInvokeDynamic node) {
     Selector selector = getOptimizedSelectorFor(node, node.selector);
-    world.registerDynamicGetter(selector.name, selector);
-    world.registerInstantiatedClass(
-        compiler.functionClass, work.resolutionTree);
-    registerInvoke(node, selector);
+    world.registerDynamicGetter(selector);
   }
 
   visitInvokeDynamicSetter(HInvokeDynamicSetter node) {
@@ -1620,7 +1601,7 @@
                         backend.namer.invocationName(call),
                         visitArguments(node.inputs)),
          node);
-    world.registerDynamicInvocation(call.name, call);
+    world.registerDynamicInvocation(call);
   }
 
   visitInvokeStatic(HInvokeStatic node) {
@@ -1998,8 +1979,6 @@
   void visitStatic(HStatic node) {
     Element element = node.element;
     if (element.isFunction()) {
-      world.registerInstantiatedClass(
-          compiler.functionClass, work.resolutionTree);
       push(new js.VariableUse(
           backend.namer.isolateStaticClosureAccess(node.element)));
     } else {
@@ -2223,7 +2202,6 @@
     assert(invariant(input, !type.isMalformed,
                      message: 'Attempt to check malformed type $type'));
     Element element = type.element;
-
     if (element == backend.jsArrayClass) {
       checkArray(input, negative ? '!==': '===');
       return;
@@ -2503,6 +2481,9 @@
       return;
     }
     if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) {
+      // An int check if the input is not int or null, is not
+      // sufficient for doing a argument or receiver check.
+      assert(!node.isInteger() || node.checkedInput.isIntegerOrNull());
       js.Expression test = generateTest(node);
       js.Block oldContainer = currentContainer;
       js.Statement body = new js.Block.empty();
@@ -2524,6 +2505,7 @@
 
     assert(node.isCheckedModeCheck || node.isCastTypeCheck);
     DartType type = node.typeExpression;
+    assert(type.kind != TypeKind.TYPEDEF);
     if (type.kind == TypeKind.FUNCTION) {
       // TODO(5022): We currently generate $isFunction checks for
       // function types.
@@ -2532,53 +2514,17 @@
     }
     world.registerIsCheck(type, work.resolutionTree);
 
+    CheckedModeHelper helper;
     FunctionElement helperElement;
     if (node.isBooleanConversionCheck) {
-      helperElement =
-          compiler.findHelper(const SourceString('boolConversionCheck'));
+      helper =
+          const CheckedModeHelper(const SourceString('boolConversionCheck'));
     } else {
-      helperElement = backend.getCheckedModeHelper(type,
-          typeCast: node.isCastTypeCheck);
+      helper =
+          backend.getCheckedModeHelper(type, typeCast: node.isCastTypeCheck);
     }
-    world.registerStaticUse(helperElement);
-    List<js.Expression> arguments = <js.Expression>[];
-    use(node.checkedInput);
-    arguments.add(pop());
-    int parameterCount =
-        helperElement.computeSignature(compiler).parameterCount;
-    // TODO(johnniwinther): Refactor this to avoid using the parameter count
-    // to determine how the helper should be called.
-    if (node.typeExpression.kind == TypeKind.TYPE_VARIABLE) {
-      assert(parameterCount == 2);
-      use(node.typeRepresentation);
-      arguments.add(pop());
-    } else if (parameterCount == 2) {
-      // 2 arguments implies that the method is either [propertyTypeCheck],
-      // [propertyTypeCast] or [assertObjectIsSubtype].
-      assert(!type.isMalformed);
-      String additionalArgument = backend.namer.operatorIs(type.element);
-      arguments.add(js.string(additionalArgument));
-    } else if (parameterCount == 3) {
-      // 3 arguments implies that the method is [malformedTypeCheck].
-      assert(type.isMalformed);
-      String reasons = Types.fetchReasonsFromMalformedType(type);
-      arguments.add(js.string('$type'));
-      // TODO(johnniwinther): Handle escaping correctly.
-      arguments.add(js.string(reasons));
-    } else if (parameterCount == 4) {
-      Element element = type.element;
-      String isField = backend.namer.operatorIs(element);
-      arguments.add(js.string(isField));
-      use(node.typeRepresentation);
-      arguments.add(pop());
-      String asField = backend.namer.substitutionName(element);
-      arguments.add(js.string(asField));
-    } else {
-      assert(!type.isMalformed);
-      // No additional arguments needed.
-    }
-    String helperName = backend.namer.isolateAccess(helperElement);
-    push(new js.Call(new js.VariableUse(helperName), arguments));
+
+    push(helper.generateCall(this, node));
   }
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
index d36e593e..2af8285 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
@@ -131,7 +131,11 @@
     }
 
     if (constantInterceptor == null) return null;
-    if (constantInterceptor == work.element.getEnclosingClass()) {
+
+    // If we just happen to be in an instance method of the constant
+    // interceptor, `this` is a shorter alias.
+    if (constantInterceptor == work.element.getEnclosingClass()
+        && graph.thisInstruction != null) {
       return graph.thisInstruction;
     }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 3f47849..23e9d32 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -1110,14 +1110,13 @@
 
   HInstruction convertType(Compiler compiler, DartType type, int kind) {
     if (type == null) return this;
+    type = type.unalias(compiler);
     // Only the builder knows how to create [HTypeConversion]
     // instructions with generics. It has the generic type context
     // available.
     assert(type.kind != TypeKind.TYPE_VARIABLE);
-    // TODO(5022): Generic typedefs should not be handled here.
     assert(type.isRaw
            || type.isMalformed
-           || type.kind == TypeKind.TYPEDEF
            || type.kind == TypeKind.FUNCTION);
     if (identical(type.element, compiler.dynamicClass)) return this;
     if (identical(type.element, compiler.objectClass)) return this;
@@ -2251,6 +2250,7 @@
   final DartType typeExpression;
   final int kind;
   final Selector receiverTypeCheckSelector;
+  final bool contextIsTypeArguments;
 
   static const int NO_CHECK = 0;
   static const int CHECKED_MODE_CHECK = 1;
@@ -2262,8 +2262,11 @@
   HTypeConversion(this.typeExpression, this.kind,
                   HType type, HInstruction input,
                   [this.receiverTypeCheckSelector])
-      : super(<HInstruction>[input]) {
+      : contextIsTypeArguments = false,
+        super(<HInstruction>[input]) {
     assert(!isReceiverTypeCheck || receiverTypeCheckSelector != null);
+    assert(typeExpression == null ||
+           typeExpression.kind != TypeKind.TYPEDEF);
     sourceElement = input.sourceElement;
     instructionType = type;
   }
@@ -2271,15 +2274,35 @@
   HTypeConversion.withTypeRepresentation(this.typeExpression, this.kind,
                                          HType type, HInstruction input,
                                          HInstruction typeRepresentation)
-      : super(<HInstruction>[input, typeRepresentation]),
+      : contextIsTypeArguments = false,
+        super(<HInstruction>[input, typeRepresentation]),
         receiverTypeCheckSelector = null {
+    assert(typeExpression.kind != TypeKind.TYPEDEF);
     sourceElement = input.sourceElement;
     instructionType = type;
   }
 
-  bool get hasTypeRepresentation => inputs.length > 1;
+  HTypeConversion.withContext(this.typeExpression, this.kind,
+                              HType type, HInstruction input,
+                              HInstruction context,
+                              {bool this.contextIsTypeArguments})
+      : super(<HInstruction>[input, context]),
+        receiverTypeCheckSelector = null {
+    assert(typeExpression.kind != TypeKind.TYPEDEF);
+    sourceElement = input.sourceElement;
+    instructionType = type;
+  }
+
+  bool get hasTypeRepresentation {
+    return typeExpression.kind == TypeKind.INTERFACE && inputs.length > 1;
+  }
   HInstruction get typeRepresentation => inputs[1];
 
+  bool get hasContext {
+    return typeExpression.kind == TypeKind.FUNCTION && inputs.length > 1;
+  }
+  HInstruction get context => inputs[1];
+
   HInstruction convertType(Compiler compiler, DartType type, int kind) {
     if (typeExpression == type) return this;
     return super.convertType(compiler, type, kind);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index ce291f2..f8ef54e 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -596,8 +596,14 @@
   HInstruction visitTypeConversion(HTypeConversion node) {
     HInstruction value = node.inputs[0];
     DartType type = node.typeExpression;
-    if (type != null && (!type.isRaw || type.kind == TypeKind.TYPE_VARIABLE)) {
-      return node;
+    if (type != null) {
+      if (!type.isRaw || type.kind == TypeKind.TYPE_VARIABLE) {
+        return node;
+      }
+      if (type.kind == TypeKind.FUNCTION) {
+        // TODO(johnniwinther): Optimize function type conversions.
+        return node;
+      }
     }
     HType convertedType = node.instructionType;
     if (convertedType.isUnknown()) return node;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
index 188969a..38cc812 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
@@ -120,14 +120,11 @@
   }
 
   // [type] is either an instance of [DartType] or special objects
-  // like [native.SpecialType.JsObject], or [native.SpecialType.JsArray].
+  // like [native.SpecialType.JsObject].
   static HType fromNativeType(type, Compiler compiler) {
     if (type == native.SpecialType.JsObject) {
       return new HType.nonNullExact(
           compiler.objectClass.computeType(compiler), compiler);
-    } else if (type == native.SpecialType.JsArray) {
-      JavaScriptBackend backend = compiler.backend;
-      return backend.readableArrayType;
     } else if (type.isVoid) {
       return HType.NULL;
     } else if (type.element == compiler.nullClass) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
index 9ff7a6c..2afc618 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
@@ -148,6 +148,24 @@
     return inputsType;
   }
 
+  HType visitTypeConversion(HTypeConversion instruction) {
+    HType oldType = instruction.instructionType;
+    // Do not change a checked mode check.
+    if (instruction.isCheckedModeCheck) return oldType;
+    // We must make sure a type conversion for receiver or argument check
+    // does not try to do an int check, because an int check is not enough.
+    // We only do an int check if the input is integer or null.
+    HInstruction checked = instruction.checkedInput;
+    if (oldType.isNumber()
+        && !oldType.isDouble()
+        && checked.isIntegerOrNull()) {
+      return HType.INTEGER;
+    } else if (oldType.isInteger() && !checked.isIntegerOrNull()) {
+      return HType.NUMBER;
+    }
+    return oldType;
+  }
+
   void convertInput(HInvokeDynamic instruction,
                     HInstruction input,
                     HType type,
@@ -231,13 +249,14 @@
     Selector selector = instruction.selector;
     if (selector.isOperator() && receiverType.isNumber()) {
       if (right.isNumber()) return false;
+      HType type = right.isIntegerOrNull() ? HType.INTEGER : HType.NUMBER;
       // TODO(ngeoffray): Some number operations don't have a builtin
       // variant and will do the check in their method anyway. We
       // still add a check because it allows to GVN these operations,
       // but we should find a better way.
       convertInput(instruction,
                    right,
-                   HType.NUMBER,
+                   type,
                    HTypeConversion.ARGUMENT_TYPE_CHECK);
       return true;
     }
@@ -331,10 +350,6 @@
         instruction, input, compiler);
   }
 
-  HType visitNot(HNot instruction) {
-    return HType.BOOLEAN;
-  }
-
   HType visitPhi(HPhi phi) {
     // Best case scenario for a phi is, when all inputs have the same type. If
     // there is no desired outgoing type we therefore try to unify the input
@@ -455,6 +470,9 @@
     // TODO(ngeoffray): Allow speculative optimizations on
     // non-primitive types?
     if (!desiredType.isPrimitive(compiler)) return newType;
+    // It's not worth having a bailout method just because we want a
+    // boolean. Comparing to true is enough.
+    if (desiredType.isBooleanOrNull()) return newType;
     desiredType = newType.intersection(desiredType, compiler);
     if (desiredType != newType && !hasBeenSpeculativelyOptimized(instruction)) {
       savedTypes[instruction] = oldType;
diff --git a/sdk/lib/_internal/compiler/implementation/tree/nodes.dart b/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
index 9a3c43c..81a51d3 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
@@ -369,15 +369,32 @@
   bool get isParameterCheck =>
       isOperator && identical(selector.asOperator().source.stringValue, '?');
 
+  bool get isTypeCast {
+    return isOperator
+        && identical(selector.asOperator().source.stringValue, 'as');
+  }
+
+  bool get isTypeTest {
+    return isOperator
+        && identical(selector.asOperator().source.stringValue, 'is');
+  }
+
+  bool get isIsCheck {
+    return isOperator
+        && identical(selector.asOperator().source.stringValue, 'is')
+        && arguments.head.asSend() == null;
+  }
+
   bool get isIsNotCheck {
     return isOperator
         && identical(selector.asOperator().source.stringValue, 'is')
         && arguments.head.asSend() != null;
   }
 
-  TypeAnnotation get typeAnnotationFromIsCheck {
-    assert(isOperator
-        && identical(selector.asOperator().source.stringValue, 'is'));
+  TypeAnnotation get typeAnnotationFromIsCheckOrCast {
+    assert(isOperator);
+    assert(identical(selector.asOperator().source.stringValue, 'is') ||
+        identical(selector.asOperator().source.stringValue, 'as'));
     return isIsNotCheck
         ? arguments.head.asSend().receiver
         : arguments.head;
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index 49612a9..78f4c8a 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -506,6 +506,10 @@
    */
   ElementAccess computeAccess(Send node, SourceString name, Element element,
                               MemberKind memberKind) {
+    if (element != null && element.isErroneous()) {
+      // An error has already been reported for this node.
+      return const DynamicAccess();
+    }
     if (node.receiver != null) {
       Element receiverElement = elements[node.receiver];
       if (receiverElement != null) {
@@ -557,6 +561,16 @@
     } else if (element.isErroneous()) {
       // foo() where foo is erroneous.
       return const DynamicAccess();
+    } else if (element.impliesType()) {
+      // The literal `Foo` where Foo is a class, a typedef, or a type variable.
+      if (elements.getType(node) != null) {
+        assert(invariant(node, identical(compiler.typeClass,
+            elements.getType(node).element),
+            message: 'Expected type literal type: '
+              '${elements.getType(node)}'));
+        return new TypeLiteralAccess(element);
+      }
+      return createResolvedAccess(node, name, element);
     } else if (element.isMember()) {
       // foo() where foo is an instance member.
       return lookupMember(node, currentClass.computeType(compiler),
@@ -569,16 +583,6 @@
         element.isField()) {
       // foo() where foo is a field in the same class.
       return createResolvedAccess(node, name, element);
-    } else if (element.impliesType()) {
-      // The literal `Foo` where Foo is a class, a typedef, or a type variable.
-      if (elements.getType(node) != null) {
-        assert(invariant(node, identical(compiler.typeClass,
-            elements.getType(node).element),
-            message: 'Expected type literal type: '
-              '${elements.getType(node)}'));
-        return new TypeLiteralAccess(element);
-      }
-      return createResolvedAccess(node, name, element);
     } else if (element.isGetter() || element.isSetter()) {
       return createResolvedAccess(node, name, element);
     } else {
diff --git a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
index ee5ccd5..c7af6a1 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -470,6 +470,18 @@
     throw new UnsupportedError("");
   }
 
+  bool get isContainer {
+    throw new UnsupportedError("");
+  }
+
+  bool get isForwarding {
+    throw new UnsupportedError("");
+  }
+
+  bool get isElement {
+    throw new UnsupportedError("");
+  }
+
   bool containsOnlyInt(Compiler compiler) {
     throw new UnsupportedError("");
   }
@@ -1142,9 +1154,6 @@
       // TODO(polux): track native types
       if (type == native.SpecialType.JsObject) {
         return unknownConcreteType;
-      } else if (type == native.SpecialType.JsArray) {
-        concreteType = singletonConcreteType(baseTypes.listBaseType);
-
       // at this point, we know that type is not a SpecialType and thus has to
       // be a DartType
       } else if (type.element == compiler.objectClass) {
diff --git a/sdk/lib/_internal/compiler/implementation/types/container_tracer.dart b/sdk/lib/_internal/compiler/implementation/types/container_tracer.dart
index 04c9923..4913c8b 100644
--- a/sdk/lib/_internal/compiler/implementation/types/container_tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/container_tracer.dart
@@ -9,7 +9,8 @@
 import '../tree/tree.dart';
 import '../universe/universe.dart';
 import '../util/util.dart' show Link;
-import 'simple_types_inferrer.dart' show SimpleTypesInferrer, InferrerVisitor;
+import 'simple_types_inferrer.dart'
+    show SimpleTypesInferrer, InferrerVisitor, LocalsHandler;
 import 'types.dart';
 
 /**
@@ -95,6 +96,8 @@
       var internal = inferrer.internal;
       // Walk over all created [ContainerTypeMask].
       internal.concreteTypes.values.forEach((ContainerTypeMask mask) {
+        // The element type has already been set for const containers.
+        if (mask.elementType != null) return;
         mask.elementType = new TracerForConcreteContainer(
             mask, this, compiler, inferrer).run();
       });
@@ -162,9 +165,8 @@
 
     // [potentialType] can be null if we did not find any instruction
     // that adds elements to the list.
-    if (potentialType == null) return new TypeMask.empty();
+    if (potentialType == null) return new TypeMask.nonNullEmpty();
 
-    potentialType = potentialType.nullable();
     // Walk over the found constraints and update the type according
     // to the selectors of these constraints.
     for (Selector constraint in constraints) {
@@ -174,7 +176,7 @@
           inferrer.getTypeOfSelector(constraint), compiler);
     }
     if (_VERBOSE) {
-      print('$potentialType for $analyzedNode');
+      print('$potentialType for $analyzedNode $startElement');
     }
     return potentialType;
   }
@@ -257,13 +259,15 @@
 class ContainerTracerVisitor extends InferrerVisitor {
   final Element analyzedElement;
   final TracerForConcreteContainer tracer;
-  ContainerTracerVisitor(element, tracer)
-      : super(element, tracer.inferrer, tracer.compiler),
+  final bool visitingClosure;
+
+  ContainerTracerVisitor(element, tracer, [LocalsHandler locals])
+      : super(element, tracer.inferrer, tracer.compiler, locals),
         this.analyzedElement = element,
-        this.tracer = tracer;
+        this.tracer = tracer,
+        visitingClosure = locals != null;
 
   bool escaping = false;
-  bool visitingClosure = false;
   bool visitingInitializers = false;
 
   void run() {
@@ -334,20 +338,22 @@
   }
 
   TypeMask visitFunctionExpression(FunctionExpression node) {
-    bool oldVisitingClosure = visitingClosure;
     FunctionElement function = elements[node];
-    FunctionSignature signature = function.computeSignature(compiler);
-    signature.forEachParameter((element) {
-      locals.update(element, inferrer.getTypeOfElement(element));
-    });
-    visitingClosure = function != analyzedElement;
-    bool oldVisitingInitializers = visitingInitializers;
-    visitingInitializers = true;
-    visit(node.initializers);
-    visitingInitializers = oldVisitingInitializers;
-    visit(node.body);
-    visitingClosure = oldVisitingClosure;
-
+    if (function != analyzedElement) {
+      // Visiting a closure.
+      LocalsHandler closureLocals = new LocalsHandler.from(locals);
+      new ContainerTracerVisitor(function, tracer, closureLocals).run();
+    } else {
+      // Visiting [analyzedElement].
+      FunctionSignature signature = function.computeSignature(compiler);
+      signature.forEachParameter((element) {
+        locals.update(element, inferrer.getTypeOfElement(element));
+      });
+      visitingInitializers = true;
+      visit(node.initializers);
+      visitingInitializers = false;
+      visit(node.body);
+    }
     return inferrer.functionType;
   }
 
@@ -518,6 +524,32 @@
 
   TypeMask visitStaticSend(Send node) {
     Element element = elements[node];
+
+    if (Elements.isGrowableListConstructorCall(element, node, compiler)) {
+      visitArguments(node.arguments, element);
+      if (tracer.couldBeTheList(node)) {
+        escaping = true;
+      }
+      return inferrer.growableListType;
+    } else if (Elements.isFixedListConstructorCall(element, node, compiler)) {
+      tracer.unionPotentialTypeWith(inferrer.nullType);
+      visitArguments(node.arguments, element);
+      if (tracer.couldBeTheList(node)) {
+        escaping = true;
+      }
+      return inferrer.fixedListType;
+    } else if (Elements.isFilledListConstructorCall(element, node, compiler)) {
+      if (tracer.couldBeTheList(node)) {
+        escaping = true;
+        visit(node.arguments.head);
+        TypeMask fillWithType = visit(node.arguments.tail.head);
+        tracer.unionPotentialTypeWith(fillWithType);
+      } else {
+        visitArguments(node.arguments, element);
+      }
+      return inferrer.fixedListType;
+    }
+
     bool isEscaping = visitArguments(node.arguments, element);
 
     if (element.isForeign(compiler)) {
@@ -528,17 +560,7 @@
       escaping = true;
     }
 
-    if (Elements.isGrowableListConstructorCall(element, node, compiler)) {
-      if (tracer.couldBeTheList(node)) {
-        escaping = true;
-      }
-      return inferrer.growableListType;
-    } else if (Elements.isFixedListConstructorCall(element, node, compiler)) {
-      if (tracer.couldBeTheList(node)) {
-        escaping = true;
-      }
-      return inferrer.fixedListType;
-    } else if (element.isFunction() || element.isConstructor()) {
+    if (element.isFunction() || element.isConstructor()) {
       return inferrer.getReturnTypeOfElement(element);
     } else {
       // Closure call or unresolved.
diff --git a/sdk/lib/_internal/compiler/implementation/types/container_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/container_type_mask.dart
index 3684755..f74db6e 100644
--- a/sdk/lib/_internal/compiler/implementation/types/container_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/container_type_mask.dart
@@ -15,11 +15,10 @@
 /// A [ContainerTypeMask] is a [TypeMask] for a specific allocation
 /// site of a container (currently only List) that will get specialized
 /// once the [ListTracer] phase finds an element type for it.
-class ContainerTypeMask implements TypeMask {
-
+class ContainerTypeMask extends ForwardingTypeMask {
   // The flat version of a [ContainerTypeMask] is the container type
   // (for example List).
-  final FlatTypeMask asFlat;
+  final FlatTypeMask forwardTo;
 
   // The [Node] where this type mask was created.
   final Node allocationNode;
@@ -36,7 +35,7 @@
     holder.elementType = mask;
   }
 
-  ContainerTypeMask(this.asFlat,
+  ContainerTypeMask(this.forwardTo,
                     this.allocationNode,
                     this.allocationElement,
                     [holder])
@@ -45,7 +44,7 @@
   TypeMask nullable() {
     return isNullable
         ? this
-        : new ContainerTypeMask(asFlat.nullable(),
+        : new ContainerTypeMask(forwardTo.nullable(),
                                 allocationNode,
                                 allocationElement,
                                 holder);
@@ -53,79 +52,29 @@
 
   TypeMask nonNullable() {
     return isNullable
-        ? new ContainerTypeMask(asFlat.nonNullable(),
+        ? new ContainerTypeMask(forwardTo.nonNullable(),
                                 allocationNode,
                                 allocationElement,
                                 holder)
         : this;
   }
 
-  TypeMask simplify(Compiler compiler) => this;
-
-  bool get isEmpty => false;
-  bool get isNullable => asFlat.isNullable;
-  bool get isExact => true;
-  bool get isUnion => false;
   bool get isContainer => true;
+  bool get isExact => true;
 
-  bool containsOnlyInt(Compiler compiler) => false;
-  bool containsOnlyDouble(Compiler compiler) => false;
-  bool containsOnlyNum(Compiler compiler) => false;
-  bool containsOnlyNull(Compiler compiler) => false;
-  bool containsOnlyBool(Compiler compiler) => false;
-  bool containsOnlyString(Compiler compiler) => false;
-  bool containsOnly(ClassElement element) {
-    return asFlat.containsOnly(element);
-  }
-
-  bool satisfies(ClassElement cls, Compiler compiler) {
-    return asFlat.satisfies(cls, compiler);
-  }
-
-  bool contains(DartType type, Compiler compiler) {
-    return asFlat.contains(type, compiler);
-  }
-
-  bool containsAll(Compiler compiler) => false;
-
-  ClassElement singleClass(Compiler compiler) {
-    return asFlat.singleClass(compiler);
-  }
-
-  Iterable<ClassElement> containedClasses(Compiler compiler) {
-    return asFlat.containedClasses(compiler);
-  }
-
-  TypeMask union(other, Compiler compiler) {
-    if (other.isContainer
-        && other.allocationNode == this.allocationNode) {
-      return other.isNullable ? other : this;
-    } else if (other.isEmpty) {
-      return other.isNullable ? this.nullable() : this;
-    }
-    return asFlat.union(other, compiler);
+  bool equalsDisregardNull(other) {
+    if (other is! ContainerTypeMask) return false;
+    return allocationNode == other.allocationNode;
   }
 
   TypeMask intersection(TypeMask other, Compiler compiler) {
-    TypeMask flatIntersection = asFlat.intersection(other, compiler);
-    if (flatIntersection.isEmpty) return flatIntersection;
-    return flatIntersection.isNullable
+    TypeMask forwardIntersection = forwardTo.intersection(other, compiler);
+    if (forwardIntersection.isEmpty) return forwardIntersection;
+    return forwardIntersection.isNullable
         ? nullable()
         : nonNullable();
   }
 
-  bool willHit(Selector selector, Compiler compiler) {
-    return asFlat.willHit(selector, compiler);
-  }
-
-  bool canHit(Element element, Selector selector, Compiler compiler) {
-    return asFlat.canHit(element, selector, compiler);
-  }
-
-  Element locateSingleElement(Selector selector, Compiler compiler) {
-    return asFlat.locateSingleElement(selector, compiler);
-  }
-
   bool operator==(other) {
     if (other is! ContainerTypeMask) return false;
     return allocationNode == other.allocationNode
diff --git a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
index c96f28d..3013586 100644
--- a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
@@ -62,8 +62,11 @@
   bool get isEmpty => (flags >> 1) == EMPTY;
   bool get isExact => (flags >> 1) == EXACT;
   bool get isNullable => (flags & 1) != 0;
+
   bool get isUnion => false;
   bool get isContainer => false;
+  bool get isForwarding => false;
+  bool get isElement => false;
 
   // TODO(kasperl): Get rid of these. They should not be a visible
   // part of the implementation because they make it hard to add
@@ -426,11 +429,18 @@
           || compiler.world.hasAnySubclassThatMixes(self, other);
     } else {
       assert(isSubtype);
-      return hasElementIn(self, selector, element, compiler)
+      bool result = hasElementIn(self, selector, element, compiler)
           || other.implementsInterface(self)
-          || other.isSubclassOf(self)
-          || compiler.world.hasAnySubclassThatMixes(self, other)
           || compiler.world.hasAnySubclassThatImplements(other, base);
+      if (result) return true;
+      // If the class is used as a mixin, we have to check if the element
+      // can be hit from any of the mixin applications.
+      Iterable<ClassElement> mixinUses = compiler.world.mixinUses[self];
+      if (mixinUses == null) return false;
+      return mixinUses.any((mixinApplication) =>
+           hasElementIn(mixinApplication, selector, element, compiler)
+        || other.isSubclassOf(mixinApplication)
+        || compiler.world.hasAnySubclassThatMixes(mixinApplication, other));
     }
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart b/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
index 75e35e1..81d00bb 100644
--- a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
@@ -31,9 +31,9 @@
  * Returns the least upper bound between [firstType] and
  * [secondType].
  */
- TypeMask computeLUB(TypeMask firstType,
-                     TypeMask secondType,
-                     Compiler compiler) {
+TypeMask computeLUB(TypeMask firstType,
+                    TypeMask secondType,
+                    Compiler compiler) {
   TypeMask dynamicType = compiler.typesTask.dynamicType;
   if (firstType == null) {
     return secondType;
@@ -41,6 +41,8 @@
     return secondType;
   } else if (firstType == dynamicType) {
     return firstType;
+  } else if (firstType == secondType) {
+    return firstType;
   } else {
     TypeMask union = firstType.union(secondType, compiler);
     // TODO(kasperl): If the union isn't nullable it seems wasteful
@@ -60,11 +62,11 @@
   final Map<Element, TypeMask> fieldsInitializedInConstructor;
   final bool inTryBlock;
   bool isThisExposed;
-  bool seenReturn = false;
+  bool seenReturnOrThrow = false;
   bool seenBreakOrContinue = false;
 
   bool get aborts {
-    return seenReturn || seenBreakOrContinue;
+    return seenReturnOrThrow || seenBreakOrContinue;
   }
 
   LocalsHandler(this.inferrer, this.compiler)
@@ -183,7 +185,7 @@
       fieldsInitializedInConstructor.remove(element);
     });
     isThisExposed = isThisExposed || other.isThisExposed;
-    seenReturn = seenReturn && other.seenReturn;
+    seenReturnOrThrow = seenReturnOrThrow && other.seenReturnOrThrow;
     seenBreakOrContinue = seenBreakOrContinue && other.seenBreakOrContinue;
 
     return changed;
@@ -365,7 +367,7 @@
       } else {
         if (!usePositive) continue;
       }
-      DartType type = elements.getType(node.typeAnnotationFromIsCheck);
+      DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
       Element element = elements[node.receiver];
       TypeMask existing = locals.use(element);
       TypeMask newType = narrowType(
@@ -591,7 +593,7 @@
 
   TypeMask visitThrow(Throw node) {
     node.visitChildren(this);
-    locals.seenReturn = true;
+    locals.seenReturnOrThrow = true;
     return inferrer.dynamicType;
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
index bcc73b3..e28ffaa 100644
--- a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
@@ -14,7 +14,8 @@
 import '../tree/tree.dart';
 import '../util/util.dart' show Link;
 import 'types.dart'
-    show TypesInferrer, FlatTypeMask, TypeMask, ContainerTypeMask;
+    show TypesInferrer, FlatTypeMask, TypeMask, ContainerTypeMask,
+         ElementTypeMask;
 
 // BUG(8802): There's a bug in the analyzer that makes the re-export
 // of Selector from dart2jslib.dart fail. For now, we work around that
@@ -51,17 +52,82 @@
 }
 
 /**
- * Placeholder for type information of final fields of classes.
+ * A [TypeInformation] object contains information from the inferrer
+ * on a specific [Element].
  */
-class ClassInfoForFinalFields {
+abstract class TypeInformation {
   /**
-   * Maps a final field to a map from generative constructor to the
-   * inferred type of the field in that generative constructor.
+   * Assignments on the element and the types inferred at
+   * these assignments.
    */
-  final Map<Element, Map<Node, TypeMask>> typesOfFinalFields =
-      new Map<Element, Map<Node, TypeMask>>();
+  Map<Node, TypeMask> get assignments => null;
 
   /**
+   * Callers of an element.
+   */
+  Set<Element> get callers => null;
+
+  /**
+   * Number of times the element has been processed.
+   */
+  int get analyzeCount => 0;
+  void set analyzeCount(value) {}
+
+  TypeMask get type => null;
+  void set type(value) {}
+
+  TypeMask get returnType => null;
+  void set returnType(value) {}
+
+  void addCaller(Element element) {
+    callers.add(element);
+  }
+  
+  void addAssignment(Node node, TypeMask mask) {
+    assignments[node] = mask;
+  }
+
+  void clear();
+}
+
+class FunctionTypeInformation extends TypeInformation {
+  Set<Element> callers = new Set<Element>();
+  TypeMask returnType;
+  int analyzeCount = 0;
+  bool canBeClosurized = false;
+
+  void clear() {
+    callers = null;
+  }
+}
+
+class ParameterTypeInformation extends TypeInformation {
+  Map<Node, TypeMask> assignments = new Map<Node, TypeMask>();
+  TypeMask type;
+  TypeMask defaultType;
+
+  void clear() {
+    assignments = null;
+  }
+}
+
+class FieldTypeInformation extends TypeInformation {
+  TypeMask type;
+  Set<Element> callers = new Set<Element>();
+  Map<Node, TypeMask> assignments = new Map<Node, TypeMask>();
+  int analyzeCount = 0;
+
+  void clear() {
+    assignments = null;
+    callers = null;
+  }
+}
+
+/**
+ * A class for knowing when can we compute a type for final fields.
+ */
+class ClassTypeInformation {
+  /**
    * The number of generative constructors that need to be visited
    * before we can take any decision on the type of the fields.
    * Given that all generative constructors must be analyzed before
@@ -70,20 +136,7 @@
    */
   int constructorsToVisitCount;
 
-  ClassInfoForFinalFields(this.constructorsToVisitCount);
-
-  /**
-   * Records that the generative [constructor] has inferred [type]
-   * for the final [field].
-   */
-  void recordFinalFieldType(Node node,
-                            Element constructor,
-                            Element field,
-                            TypeMask type) {
-    Map<Node, TypeMask> typesFor = typesOfFinalFields.putIfAbsent(
-        field, () => new Map<Node, TypeMask>());
-    typesFor[node] = type;
-  }
+  ClassTypeInformation(this.constructorsToVisitCount);
 
   /**
    * Records that [constructor] has been analyzed. If not at 0,
@@ -130,11 +183,11 @@
 
   TypeMask getReturnTypeOfElement(Element element) {
     if (compiler.disableTypeInference) return dynamicType;
-    return internal.getReturnTypeOfElement(element);
+    return internal.getReturnTypeOfElement(element.implementation);
   }
   TypeMask getTypeOfElement(Element element) {
     if (compiler.disableTypeInference) return dynamicType;
-    return internal.getTypeOfElement(element);
+    return internal.getTypeOfElement(element.implementation);
   }
   TypeMask getTypeOfNode(Element owner, Node node) {
     if (compiler.disableTypeInference) return dynamicType;
@@ -144,13 +197,9 @@
     if (compiler.disableTypeInference) return dynamicType;
     return internal.getTypeOfSelector(selector);
   }
-
   Iterable<Element> getCallersOf(Element element) {
     if (compiler.disableTypeInference) throw "Don't use me";
-    Iterable<Element> result = internal.callersOf[element];
-    return result == null
-        ? internal.callersOf[element] = const <Element>[]
-        : result;
+    return internal.getCallersOf(element.implementation);
   }
 
   bool analyzeMain(Element element) {
@@ -171,67 +220,25 @@
 
 class InternalSimpleTypesInferrer extends TypesInferrer {
   /**
+   * Maps a class to a [ClassTypeInformation] to help collect type
+   * information of final fields.
+   */
+  Map<ClassElement, ClassTypeInformation> classInfoForFinalFields =
+      new Map<ClassElement, ClassTypeInformation>();
+
+  /**
+   * Maps an element to its corresponding [TypeInformation].
+   */
+  final Map<Element, TypeInformation> typeInfo =
+      new Map<Element, TypeInformation>();
+
+  /**
    * Maps a node to its type. Currently used for computing element
    * types of lists.
    */
   final Map<Node, TypeMask> concreteTypes = new Map<Node, TypeMask>();
 
   /**
-   * Maps an element to its callers.
-   */
-  final Map<Element, Iterable<Element>> callersOf =
-      new Map<Element, Iterable<Element>>();
-
-  /**
-   * Maps an element to its return type.
-   */
-  final Map<Element, TypeMask> returnTypeOf =
-      new Map<Element, TypeMask>();
-
-  /**
-   * Maps an element to its type.
-   */
-  final Map<Element, TypeMask> typeOf = new Map<Element, TypeMask>();
-
-  /**
-   * Maps an element to its assignments and the types inferred at
-   * these assignments.
-   */
-  final Map<Element, Map<Node, TypeMask>> typeOfFields =
-      new Map<Element, Map<Node, TypeMask>>();
-
-  /**
-   * Maps an element to the type of its parameters at call sites.
-   */
-  final Map<Element, Map<Node, ArgumentsTypes>> typeOfArguments =
-      new Map<Element, Map<Node, ArgumentsTypes>>();
-
-  /**
-   * Maps an optional parameter to its default type.
-   */
-  final Map<Element, TypeMask> defaultTypeOfParameter =
-      new Map<Element, TypeMask>();
-
-  /**
-   * Set of methods that the inferrer found could be closurized. We
-   * don't compute parameter types for such methods.
-   */
-  final Set<Element> methodsThatCanBeClosurized = new Set<Element>();
-
-  /**
-   * Maps an element to the number of times this type inferrer
-   * analyzed it.
-   */
-  final Map<Element, int> analyzeCount = new Map<Element, int>();
-
-  /**
-   * Maps a class to a [ClassInfoForFinalFields] to help collect type
-   * information of final fields.
-   */
-  final Map<ClassElement, ClassInfoForFinalFields> classInfoForFinalFields =
-      new Map<ClassElement, ClassInfoForFinalFields>();
-
-  /**
    * A map of constraints on a setter. When computing the type
    * of a field, these [Node] are initially discarded, and once the
    * type is computed, we make sure these constraints are satisfied
@@ -246,12 +253,12 @@
    * returns that type.
    *
    */
-  final Map<Node, Selector> setterConstraints = new Map<Node, Selector>();
+  Map<Node, CallSite> setterConstraints = new Map<Node, CallSite>();
 
   /**
    * The work list of the inferrer.
    */
-  final WorkSet<Element> workSet = new WorkSet<Element>();
+  WorkSet<Element> workSet = new WorkSet<Element>();
 
   /**
    * Heuristic for avoiding too many re-analysis of an element.
@@ -319,6 +326,11 @@
    */
   int numberOfElementsToAnalyze;
 
+  /**
+   * The number of analysis already done.
+   */
+  int analyzed = 0;
+
   InternalSimpleTypesInferrer(this.compiler, this.optimismState);
 
   /**
@@ -327,7 +339,6 @@
    */
   bool analyzeMain(Element element) {
     buildWorkQueue();
-    int analyzed = 0;
     compiler.progress.reset();
     int maxReanalysis = (numberOfElementsToAnalyze * 1.5).toInt();
     do {
@@ -338,7 +349,7 @@
       element = workSet.remove();
       if (element.isErroneous()) continue;
 
-      bool wasAnalyzed = analyzeCount.containsKey(element);
+      bool wasAnalyzed = typeInformationOf(element).analyzeCount != 0;
       if (wasAnalyzed) {
         recompiles++;
         if (recompiles >= maxReanalysis) {
@@ -365,15 +376,28 @@
     return true;
   }
 
+  TypeInformation typeInformationOf(Element element) {
+    return typeInfo.putIfAbsent(element, () {
+      if (element.isParameter() || element.isFieldParameter()) {
+        return new ParameterTypeInformation();
+      } else if (element.isField() || element.isVariable()) {
+        return new FieldTypeInformation();
+      } else {
+        assert(element is FunctionElement);
+        return new FunctionTypeInformation();
+      }
+    });
+  }
+
   /**
    * Query method after the analysis to know the type of [element].
    */
   TypeMask getReturnTypeOfElement(Element element) {
-    return getNonNullType(returnTypeOf[element]);
+    return getNonNullType(typeInformationOf(element).returnType);
   }
 
   TypeMask getTypeOfElement(Element element) {
-    return getNonNullType(typeOf[element]);
+    return getNonNullType(typeInformationOf(element).type);
   }
 
   TypeMask getTypeOfSelector(Selector selector) {
@@ -388,6 +412,10 @@
     return returnType != null ? returnType : dynamicType;
   }
 
+  Iterable<Element> getCallersOf(Element element) {
+    return typeInformationOf(element).callers;
+  }
+
   /**
    * Query method after the analysis to know the type of [node],
    * defined in the context of [owner].
@@ -398,29 +426,39 @@
 
   void checkAnalyzedAll() {
     if (hasAnalyzedAll) return;
-    if (analyzeCount.length != numberOfElementsToAnalyze) return;
+    if (analyzed < numberOfElementsToAnalyze) return;
     hasAnalyzedAll = true;
+   
     // If we have analyzed all the world, we know all assigments to
-    // fields and can therefore infer a type for them.
-    typeOfFields.keys.forEach(updateNonFinalFieldType);
-    // We also know all calls to methods.
-    typeOfArguments.keys.forEach(updateArgumentsType);
+    // fields and parameters, and can therefore infer a type for them.
+    typeInfo.forEach((element, TypeInformation info) {
+      if (element.isParameter() || element.isFieldParameter()) {
+        if (updateParameterType(element)) {
+          enqueueAgain(element.enclosingElement);
+        }
+      } else if (element.isField()
+                 && !(element.modifiers.isFinal()
+                      || element.modifiers.isConst())) {
+        updateNonFinalFieldType(element);
+      } else if (element.isVariable()) {
+        updateNonFinalFieldType(element);
+      }
+    });
   }
 
   /**
    * Enqueues [e] in the work queue if it is valuable.
    */
   void enqueueAgain(Element e) {
-    int count = analyzeCount[e];
+    assert(isNotClosure(e));
+    int count = typeInformationOf(e).analyzeCount;
     if (count != null && count > MAX_ANALYSIS_COUNT_PER_ELEMENT) return;
     workSet.add(e);
   }
 
   void enqueueCallersOf(Element element) {
-    Set<Element> methodCallers = callersOf[element];
-    if (methodCallers != null) {
-      methodCallers.forEach(enqueueAgain);
-    }
+    assert(isNotClosure(element));
+    typeInformationOf(element).callers.forEach(enqueueAgain);
   }
 
   /**
@@ -453,7 +491,9 @@
           // Optimistically assume that they return bool.  We may need to back
           // out of this.
           if (optimismState == OPTIMISTIC) {
-            returnTypeOf[element.implementation] = boolType;
+            FunctionTypeInformation info =
+                typeInformationOf(element.implementation);
+            info.returnType = boolType;
           }
         } else {
           // Put the other operators in buckets by length, later to be added in
@@ -490,7 +530,7 @@
         }
       });
       classInfoForFinalFields[cls.implementation] =
-          new ClassInfoForFinalFields(constructorCount);
+          new ClassTypeInformation(constructorCount);
     });
   }
 
@@ -504,13 +544,15 @@
 
   dump() {
     int interestingTypes = 0;
-    returnTypeOf.forEach((Element element, TypeMask type) {
-      if (type != nullType && !isDynamicType(type)) {
+    typeInfo.forEach((element, TypeInformation info) {
+      TypeMask type = info.type;
+      TypeMask returnType = info.returnType;
+      if (type != null && type != nullType && !isDynamicType(type)) {
         interestingTypes++;
       }
-    });
-    typeOf.forEach((Element element, TypeMask type) {
-      if (type != nullType && !isDynamicType(type)) {
+      if (returnType != null
+          && returnType != nullType
+          && !isDynamicType(returnType)) {
         interestingTypes++;
       }
     });
@@ -525,11 +567,10 @@
    * Clear data structures that are not used after the analysis.
    */
   void clear() {
-    callersOf.clear();
-    analyzeCount.clear();
-    classInfoForFinalFields.clear();
-    typeOfFields.clear();
-    setterConstraints.clear();
+    classInfoForFinalFields = null;
+    setterConstraints = null;
+    workSet = null;
+    typeInfo.forEach((_, info) { info.clear(); });
   }
 
   bool analyze(Element element) {
@@ -539,11 +580,7 @@
     SimpleTypeInferrerVisitor visitor =
         new SimpleTypeInferrerVisitor(element, compiler, this);
     TypeMask returnType = visitor.run();
-    if (analyzeCount.containsKey(element)) {
-      analyzeCount[element]++;
-    } else {
-      analyzeCount[element] = 1;
-    }
+    typeInformationOf(element).analyzeCount++;
     if (element.isGenerativeConstructor()) {
       // We always know the return type of a generative constructor.
       return false;  // Nothing changed.
@@ -575,11 +612,18 @@
   }
 
   bool recordType(Element analyzedElement, TypeMask type) {
+    if (isNativeElement(analyzedElement)) return false;
     assert(type != null);
     assert(analyzedElement.isField()
            || analyzedElement.isParameter()
            || analyzedElement.isFieldParameter());
-    return internalRecordType(analyzedElement, type, typeOf);
+    TypeMask newType = checkTypeAnnotation(analyzedElement, type);
+    TypeMask existing = typeInformationOf(analyzedElement).type;
+    typeInformationOf(analyzedElement).type = newType;
+    // If the type is useful, say it has changed.
+    return existing != newType
+        && !isDynamicType(newType)
+        && newType != nullType;
   }
 
   /**
@@ -588,15 +632,23 @@
    * [analyzedElement].
    */
   bool recordReturnType(Element analyzedElement, TypeMask returnType) {
+    if (isNativeElement(analyzedElement)) return false;
     assert(analyzedElement.implementation == analyzedElement);
+    TypeMask existing = typeInformationOf(analyzedElement).returnType;
     if (optimismState == OPTIMISTIC
         && shouldOptimisticallyOptimizeToBool(analyzedElement)
-        && returnType != returnTypeOf[analyzedElement]) {
+        && returnType != existing) {
       // One of the functions turned out not to return what we expected.
       // This means we need to restart the analysis.
       optimismState = RETRY;
     }
-    return internalRecordType(analyzedElement, returnType, returnTypeOf);
+    TypeMask newType = checkTypeAnnotation(analyzedElement, returnType);
+    FunctionTypeInformation info = typeInformationOf(analyzedElement);
+    info.returnType = newType;
+    // If the return type is useful, say it has changed.
+    return existing != newType
+        && !isDynamicType(newType)
+        && newType != nullType;
   }
 
   bool isNativeElement(Element element) {
@@ -606,31 +658,32 @@
         && element.isField();
   }
 
-  bool internalRecordType(Element analyzedElement,
-                          TypeMask newType,
-                          Map<Element, TypeMask> types) {
+  TypeMask checkTypeAnnotation(Element analyzedElement, TypeMask newType) {
     if (compiler.trustTypeAnnotations
         // Parameters are being checked by the method, and we can
         // therefore only trust their type after the checks.
         || (compiler.enableTypeAssertions && !analyzedElement.isParameter())) {
       var annotation = analyzedElement.computeType(compiler);
-      if (types == returnTypeOf) {
+      if (analyzedElement.isGetter()
+          || analyzedElement.isFunction()
+          || analyzedElement.isConstructor()
+          || analyzedElement.isSetter()) {
         assert(annotation is FunctionType);
         annotation = annotation.returnType;
       }
       newType = narrowType(newType, annotation, compiler);
     }
+    return newType;
+  }
 
-    // Fields and native methods of native classes are handled
-    // specially when querying for their type or return type.
-    if (isNativeElement(analyzedElement)) return false;
-    assert(newType != null);
-    TypeMask existing = types[analyzedElement];
-    types[analyzedElement] = newType;
-    // If the return type is useful, say it has changed.
-    return existing != newType
-        && !isDynamicType(newType)
-        && newType != nullType;
+  TypeMask fetchReturnType(Element element) {
+    TypeMask returnType = typeInformationOf(element).returnType;
+    return returnType is ElementTypeMask ? dynamicType : returnType;
+  }
+
+  TypeMask fetchType(Element element) {
+    TypeMask type = typeInformationOf(element).type;
+    return type is ElementTypeMask ? dynamicType : type;
   }
 
   /**
@@ -639,22 +692,25 @@
    */
   TypeMask returnTypeOfElement(Element element) {
     element = element.implementation;
+    TypeInformation info = typeInformationOf(element);
     if (element.isGenerativeConstructor()) {
-      return returnTypeOf.putIfAbsent(element, () {
-        return new TypeMask.nonNullExact(
-            rawTypeOf(element.getEnclosingClass()));
-      });
+      return info.returnType == null
+          ? info.returnType = new TypeMask.nonNullExact(
+                rawTypeOf(element.getEnclosingClass()))
+          : info.returnType;
     } else if (element.isNative()) {
-      return returnTypeOf.putIfAbsent(element, () {
+      if (info.returnType == null) {
         var elementType = element.computeType(compiler);
         if (elementType.kind != TypeKind.FUNCTION) {
-          return dynamicType;
-        }
-        return typeOfNativeBehavior(
+          info.returnType = dynamicType;
+        } else {
+          info.returnType = typeOfNativeBehavior(
             native.NativeBehavior.ofMethod(element, compiler));
-      });
+        }
+      }
+      return info.returnType;
     }
-    TypeMask returnType = returnTypeOf[element];
+    TypeMask returnType = info.returnType;
     if (returnType == null) {
       if ((compiler.trustTypeAnnotations || compiler.enableTypeAssertions)
           && (element.isFunction()
@@ -663,7 +719,8 @@
         FunctionType functionType = element.computeType(compiler);
         returnType = narrowType(dynamicType, functionType.returnType, compiler);
       } else {
-        returnType = dynamicType;
+        returnType = info.returnType =
+            new ElementTypeMask(fetchReturnType, element);
       }
     }
     return returnType;
@@ -678,8 +735,6 @@
       TypeMask mappedType;
       if (type == native.SpecialType.JsObject) {
         mappedType = new TypeMask.nonNullExact(rawTypeOf(compiler.objectClass));
-      } else if (type == native.SpecialType.JsArray) {
-        mappedType = listType;
       } else if (type.element == compiler.stringClass) {
         mappedType = stringType;
       } else if (type.element == compiler.intClass) {
@@ -696,12 +751,17 @@
         mappedType = nullType;
       } else if (type.isDynamic) {
         return dynamicType;
-      } else if (compiler.world.hasAnySubclass(type.element)) {
-        mappedType = new TypeMask.nonNullSubclass(rawTypeOf(type.element));
-      } else if (compiler.world.hasAnySubtype(type.element)) {
-        mappedType = new TypeMask.nonNullSubtype(rawTypeOf(type.element));
-      } else {
+      } else if (!compiler.world.hasAnySubtype(type.element)) {
         mappedType = new TypeMask.nonNullExact(rawTypeOf(type.element));
+      } else {
+        Element element = type.element;
+        Set<ClassElement> subtypes = compiler.world.subtypesOf(element);
+        Set<ClassElement> subclasses = compiler.world.subclassesOf(element);
+        if (subclasses != null && subtypes.length == subclasses.length) {
+          mappedType = new TypeMask.nonNullSubclass(rawTypeOf(element));
+        } else {
+          mappedType = new TypeMask.nonNullSubtype(rawTypeOf(element));
+        }
       }
       returnType = computeLUB(returnType, mappedType, compiler);
       if (!isTypeValuable(returnType)) {
@@ -719,15 +779,18 @@
    */
   TypeMask typeOfElement(Element element) {
     element = element.implementation;
+    TypeInformation info = typeInformationOf(element);
+    TypeMask type = info.type;
     if (isNativeElement(element) && element.isField()) {
-      var type = typeOf.putIfAbsent(element, () {
+      if (type == null) {
         InterfaceType rawType = element.computeType(compiler).asRaw();
-        return rawType.isDynamic ? dynamicType : new TypeMask.subtype(rawType);
-      });
+        info.type = type = rawType.isDynamic
+            ? dynamicType
+            : new TypeMask.subtype(rawType);
+      }
       assert(type != null);
       return type;
     }
-    TypeMask type = typeOf[element];
     if (type == null) {
       if ((compiler.trustTypeAnnotations
            && (element.isField()
@@ -739,7 +802,7 @@
               && (element.isField() || element.isVariable()))) {
         type = narrowType(dynamicType, element.computeType(compiler), compiler);
       } else {
-        type = dynamicType;
+        type = info.type = new ElementTypeMask(fetchType, element);
       }
     }
     return type;
@@ -791,9 +854,8 @@
       ContainerTypeMask mask = selector.mask;
       TypeMask elementType = mask.elementType;
       return elementType == null ? dynamicType : elementType;
-    } else if (element.isGetter()) {
-      // Closure call.
-      assert(selector.isCall());
+    } else if (element.isGetter() || element.isField()) {
+      assert(selector.isCall() || selector.isSetter());
       return dynamicType;
     } else {
       return returnTypeOfElement(element);
@@ -811,17 +873,74 @@
     assert(caller.isImplementation);
     assert(callee.isImplementation);
     assert(isNotClosure(caller));
-    Set<Element> callers = callersOf.putIfAbsent(
-        callee, () => new Set<Element>());
+    Set<Element> callers = typeInformationOf(callee).callers;
     callers.add(caller);
   }
 
-  bool addArguments(Node node, Element element, ArgumentsTypes arguments) {
-    Map<Node, ArgumentsTypes> types = typeOfArguments.putIfAbsent(
-        element, () => new Map<Node, ArgumentsTypes>());
-    ArgumentsTypes existing = types[node];
-    types[node] = arguments;
-    return existing != arguments;
+  bool addArguments(Node node,
+                    FunctionElement element,
+                    ArgumentsTypes arguments) {
+    FunctionTypeInformation info = typeInformationOf(element);
+    if (info.canBeClosurized) return false;
+    // A [noSuchMethod] method can be the target of any call, with
+    // any number of arguments. For simplicity, we just do not
+    // infer any parameter types for [noSuchMethod].
+    if (element.name == Compiler.NO_SUCH_METHOD) return false;
+
+    FunctionSignature signature = element.computeSignature(compiler);
+    int parameterIndex = 0;
+    bool changed = false;
+    bool visitingOptionalParameter = false;
+    signature.forEachParameter((Element parameter) {
+      if (parameter == signature.firstOptionalParameter) {
+        visitingOptionalParameter = true;
+      }
+      TypeMask type;
+      ParameterTypeInformation info = typeInformationOf(parameter);
+      if (!visitingOptionalParameter) {
+        type = arguments.positional[parameterIndex];
+      } else {
+        type = signature.optionalParametersAreNamed
+            ? arguments.named[parameter.name]
+            : parameterIndex < arguments.positional.length
+                ? arguments.positional[parameterIndex]
+                : info.defaultType;
+      }
+      TypeMask oldType = info.assignments[node];
+      info.addAssignment(node, type);
+      changed = changed || (oldType != type);
+      parameterIndex++;
+    });
+    return changed;
+  }
+
+  bool updateParameterType(Element parameter) {
+    FunctionTypeInformation functionInfo =
+        typeInformationOf(parameter.enclosingElement);
+    if (functionInfo.canBeClosurized) return false;
+    if (!isNotClosure(parameter.enclosingElement)) return false;
+
+    ParameterTypeInformation info = typeInformationOf(parameter);
+    TypeMask elementType;
+    info.assignments.forEach((Node node, TypeMask mask) {
+      if (mask == null) {
+        // Now that we know we have analyzed the function holding
+        // [parameter], we have a default type for that [parameter].
+        mask = info.defaultType;
+        info.addAssignment(node, mask);
+      }
+      elementType = computeLubFor(elementType, mask, parameter);
+    });
+    if (elementType == null) {
+      elementType = dynamicType;
+    }
+    return recordType(parameter, elementType);
+  }
+
+  void updateAllParametersOf(FunctionElement function) {
+    function.computeSignature(compiler).forEachParameter((Element parameter) {
+      updateParameterType(parameter);
+    });
   }
 
   void updateSideEffects(SideEffects sideEffects,
@@ -865,7 +984,7 @@
                              Element caller,
                              Element callee,
                              ArgumentsTypes arguments,
-                             Selector constraint,
+                             CallSite constraint,
                              SideEffects sideEffects,
                              bool inLoop) {
     updateSideEffects(sideEffects, selector, callee);
@@ -890,18 +1009,21 @@
 
     assert(isNotClosure(caller));
     callee = callee.implementation;
-    if (!analyzeCount.containsKey(caller)) {
-      addCaller(caller, callee);
-    }
+    TypeInformation info = typeInformationOf(callee);
+    info.addCaller(caller);
 
     if (selector.isSetter() && callee.isField()) {
       recordNonFinalFieldElementType(
-          node, callee, arguments.positional[0], constraint);
+          node,
+          callee,
+          arguments.positional[0],
+          constraint);
       return;
     } else if (selector.isGetter()) {
       assert(arguments == null);
       if (callee.isFunction()) {
-        methodsThatCanBeClosurized.add(callee);
+        FunctionTypeInformation functionInfo = info;
+        functionInfo.canBeClosurized = true;
       }
       return;
     } else if (callee.isField()) {
@@ -927,74 +1049,37 @@
                                Element callee) {
     if (callee.isField()) {
       if (selector.isSetter()) {
-        Map<Node, TypeMask> types = typeOfFields[callee];
-        if (types == null || !types.containsKey(node)) return;
-        types.remove(node);
+        Map<Node, TypeMask> assignments = typeInformationOf(callee).assignments;
+        if (assignments == null || !assignments.containsKey(node)) return;
+        assignments.remove(node);
         if (hasAnalyzedAll) updateNonFinalFieldType(callee);
       }
     } else if (callee.isGetter()) {
       return;
     } else {
-      Map<Node, ArgumentsTypes> types = typeOfArguments[callee];
-      if (types == null || !types.containsKey(node)) return;
-      types.remove(node);
-      if (hasAnalyzedAll) enqueueAgain(callee);
+      FunctionElement element = callee;
+      element.computeSignature(compiler).forEachParameter((Element parameter) {
+        Map<Node, TypeMask> assignments =
+            typeInformationOf(parameter).assignments;
+        if (assignments == null || !assignments.containsKey(node)) return;
+        assignments.remove(node);
+        if (hasAnalyzedAll) enqueueAgain(callee);
+      });
     }
   }
 
-  /**
-   * Computes the parameter types of [element], based on all call sites we
-   * have collected on that [element]. This method can only be called after
-   * we have analyzed all elements in the world.
-   */
-  void updateArgumentsType(FunctionElement element) {
-    assert(hasAnalyzedAll);
-    if (methodsThatCanBeClosurized.contains(element)) return;
-    // A [noSuchMethod] method can be the target of any call, with
-    // any number of arguments. For simplicity, we just do not
-    // infer any parameter types for [noSuchMethod].
-    if (element.name == Compiler.NO_SUCH_METHOD) return;
-    FunctionSignature signature = element.computeSignature(compiler);
-
-    if (typeOfArguments[element] == null || typeOfArguments[element].isEmpty) {
-      signature.forEachParameter((Element parameter) {
-        typeOf.remove(parameter);
-      });
-      return;
+  TypeMask computeLubFor(TypeMask firstType,
+                         TypeMask secondType,
+                         Element element) {
+    if (secondType.isElement) {
+      ElementTypeMask mask = secondType;
+      if (element == mask.element) {
+        // Simple constraint of the abstract form [: foo = foo :], for
+        // example a recursive function passing the same parameter.
+        return firstType;
+      }
     }
-
-    int parameterIndex = 0;
-    bool changed = false;
-    bool visitingOptionalParameter = false;
-    signature.forEachParameter((Element parameter) {
-      if (parameter == signature.firstOptionalParameter) {
-        visitingOptionalParameter = true;
-      }
-      TypeMask type;
-      typeOfArguments[element].forEach((_, ArgumentsTypes arguments) {
-        if (!visitingOptionalParameter) {
-          type = computeLUB(
-              type, arguments.positional[parameterIndex], compiler);
-        } else {
-          TypeMask argumentType = signature.optionalParametersAreNamed
-              ? arguments.named[parameter.name]
-              : parameterIndex < arguments.positional.length
-                  ? arguments.positional[parameterIndex]
-                  : null;
-          if (argumentType == null) {
-            argumentType = defaultTypeOfParameter[parameter];
-          }
-          assert(argumentType != null);
-          type = computeLUB(type, argumentType, compiler);
-        }
-      });
-      if (recordType(parameter, type)) {
-        changed = true;
-      }
-      parameterIndex++;
-    });
-
-    if (changed) enqueueAgain(element);
+    return computeLUB(firstType, secondType, compiler);
   }
 
   TypeMask handleIntrisifiedSelector(Selector selector,
@@ -1031,7 +1116,7 @@
                                   TypeMask receiverType,
                                   Element caller,
                                   ArgumentsTypes arguments,
-                                  Selector constraint,
+                                  CallSite constraint,
                                   SideEffects sideEffects,
                                   bool inLoop) {
     TypeMask result;
@@ -1080,11 +1165,10 @@
   void recordNonFinalFieldElementType(Node node,
                                       Element element,
                                       TypeMask argumentType,
-                                      Selector constraint) {
-    Map<Node, TypeMask> map =
-        typeOfFields.putIfAbsent(element, () => new Map<Node, TypeMask>());
-    map[node] = argumentType;
-    bool changed = typeOf[element] != argumentType;
+                                      CallSite constraint) {
+    TypeInformation info = typeInformationOf(element);
+    info.addAssignment(node, argumentType);
+    bool changed = info.type != argumentType;
     if (constraint != null && constraint != setterConstraints[node]) {
       changed = true;
       setterConstraints[node] = constraint;
@@ -1096,48 +1180,54 @@
     }
   }
 
-  TypeMask computeFieldTypeWithConstraints(Element element, Map types) {
-    Set<Selector> constraints = new Set<Selector>();
-    TypeMask fieldType;
+  TypeMask computeTypeWithConstraints(Element element,
+                                      Map<Node, TypeMask> types) {
+    List<CallSite> constraints = <CallSite>[];
+    TypeMask elementType;
     types.forEach((Node node, TypeMask mask) {
-      Selector constraint = setterConstraints[node];
+      CallSite constraint = setterConstraints[node];
       if (constraint != null) {
         // If this update has a constraint, we collect it and don't
         // use its type.
         constraints.add(constraint);
       } else {
-        fieldType = computeLUB(fieldType, mask, compiler);
+        elementType = computeLubFor(elementType, mask, element);
       }
     });
 
-    if (!constraints.isEmpty && !isDynamicType(fieldType)) {
+    if (!constraints.isEmpty && !isDynamicType(elementType)) {
       // Now that we have found a type, we go over the collected
       // constraints, and make sure they apply to the found type. We
       // update [typeOf] to make sure [typeOfSelector] knows the field
       // type.
-      TypeMask existing = typeOf[element];
-      typeOf[element] = fieldType;
+      TypeInformation info = typeInformationOf(element);
+      TypeMask existing = info.type;
+      info.type = elementType;
 
-      for (Selector constraint in constraints) {
-        if (constraint.isOperator()) {
+      for (CallSite constraint in constraints) {
+        Selector selector = constraint.selector;
+        TypeMask type;
+        if (selector.isOperator()) {
           // If the constraint is on an operator, we type the receiver
           // to be the field.
-          if (fieldType != null) {
-            constraint = new TypedSelector(fieldType, constraint);
+          if (elementType != null) {
+            selector = new TypedSelector(elementType, selector);
           }
+          type = handleIntrisifiedSelector(selector, constraint.arguments);
+          if (type == null) type = typeOfSelector(selector);
         } else {
           // Otherwise the constraint is on the form [: field = other.field :].
-          assert(constraint.isGetter());
+          assert(selector.isGetter());
+          type = typeOfSelector(selector);
         }
-        fieldType = computeLUB(fieldType, typeOfSelector(constraint), compiler);
+        elementType = computeLUB(elementType, type, compiler);
       }
-      if (existing == null) {
-        typeOf.remove(element);
-      } else {
-        typeOf[element] = existing;
-      }
+      info.type = existing;
     }
-    return fieldType;
+    if (elementType == null) {
+      elementType = new TypeMask.nonNullEmpty();
+    }
+    return elementType;
   }
 
   /**
@@ -1149,13 +1239,11 @@
     if (isNativeElement(element)) return;
     assert(hasAnalyzedAll);
 
-    if (typeOfFields[element] == null || typeOfFields[element].isEmpty) {
-      typeOf.remove(element);
-      return;
-    }
+    TypeInformation info = typeInformationOf(element);
+    Map<Node, TypeMask> assignments = info.assignments;
+    if (assignments.isEmpty) return;
 
-    TypeMask fieldType = computeFieldTypeWithConstraints(
-        element, typeOfFields[element]);
+    TypeMask fieldType = computeTypeWithConstraints(element, assignments);
 
     // If the type of [element] has changed, re-analyze its users.
     if (recordType(element, fieldType)) {
@@ -1171,7 +1259,7 @@
                             Element constructor,
                             Element field,
                             TypeMask type,
-                            Selector constraint) {
+                            CallSite constraint) {
     if (constraint != null) {
       setterConstraints[node] = constraint;
     }
@@ -1179,9 +1267,8 @@
     // being tracked in the [classInfoForFinalFields] map.
     if (constructor == field) return;
     assert(field.modifiers.isFinal() || field.modifiers.isConst());
-    ClassElement cls = constructor.getEnclosingClass();
-    ClassInfoForFinalFields info = classInfoForFinalFields[cls.implementation];
-    info.recordFinalFieldType(node, constructor, field, type);
+    TypeInformation info = typeInformationOf(field);
+    info.addAssignment(node, type);
   }
 
   /**
@@ -1191,23 +1278,26 @@
    */
   void doneAnalyzingGenerativeConstructor(Element constructor) {
     ClassElement cls = constructor.getEnclosingClass();
-    ClassInfoForFinalFields info = classInfoForFinalFields[cls.implementation];
+    ClassTypeInformation info = classInfoForFinalFields[cls.implementation];
     info.doneAnalyzingGenerativeConstructor(constructor);
     if (info.isDone) {
-      updateFinalFieldsType(info);
+      updateFinalFieldsType(info, constructor.getEnclosingClass());
     }
   }
 
   /**
    * Updates types of final fields listed in [info].
    */
-  void updateFinalFieldsType(ClassInfoForFinalFields info) {
+  void updateFinalFieldsType(ClassTypeInformation info, ClassElement cls) {
     assert(info.isDone);
-    info.typesOfFinalFields.forEach((Element field,
-                                     Map<Node, TypeMask> types) {
+    cls.forEachInstanceField((_, Element field) {
       if (isNativeElement(field)) return;
-      assert(field.modifiers.isFinal());
-      TypeMask fieldType = computeFieldTypeWithConstraints(field, types);
+      if (!field.modifiers.isFinal()) return;
+      // If the field is being set at its declaration site, it is not
+      // being tracked in the [classInfoForFinalFields] map.
+      if (field.parseNode(compiler).asSendSet() != null) return;
+      TypeInformation info = typeInformationOf(field);
+      TypeMask fieldType = computeTypeWithConstraints(field, info.assignments);
       if (recordType(field, fieldType)) {
         enqueueCallersOf(field);
       }
@@ -1215,6 +1305,14 @@
   }
 }
 
+class CallSite {
+  final Selector selector;
+  final ArgumentsTypes arguments;
+  CallSite(this.selector, this.arguments) {
+    assert(selector != null);
+  }
+}
+
 /**
  * Placeholder for inferred arguments types on sends.
  */
@@ -1298,16 +1396,16 @@
 
     FunctionElement function = analyzedElement;
     if (inferrer.hasAnalyzedAll) {
-      inferrer.updateArgumentsType(function);
+      inferrer.updateAllParametersOf(function);
     }
     FunctionSignature signature = function.computeSignature(compiler);
     signature.forEachOptionalParameter((element) {
       Node node = element.parseNode(compiler);
       Send send = node.asSendSet();
-      inferrer.defaultTypeOfParameter[element] = (send == null)
+      ParameterTypeInformation info = inferrer.typeInformationOf(element);
+      info.defaultType = (send == null)
           ? inferrer.nullType
           : visit(send.arguments.head);
-      assert(inferrer.defaultTypeOfParameter[element] != null);
     });
 
     if (analyzedElement.isNative()) {
@@ -1366,8 +1464,11 @@
       visit(node.body);
       if (returnType == null) {
         // No return in the body.
-        returnType = inferrer.nullType;
-      } else if (!locals.seenReturn && !inferrer.isDynamicType(returnType)) {
+        returnType = locals.seenReturnOrThrow
+            ? new TypeMask.nonNullEmpty()  // Body always throws.
+            : inferrer.nullType;
+      } else if (!locals.seenReturnOrThrow &&
+                 !inferrer.isDynamicType(returnType)) {
         // We haven't seen returns on all branches. So the method may
         // also return null.
         returnType = returnType.nullable();
@@ -1394,7 +1495,7 @@
       });
       // TODO(ngeoffray): Re-analyze method if [changed]?
     }
-    compiler.world.registerSideEffects(analyzedElement, sideEffects);    
+    compiler.world.registerSideEffects(analyzedElement, sideEffects);
     assert(breaksFor.isEmpty);
     assert(continuesFor.isEmpty);
     return returnType;
@@ -1431,11 +1532,25 @@
   }
 
   TypeMask visitLiteralList(LiteralList node) {
-    node.visitChildren(this);
-    if (node.isConst()) return inferrer.constListType;
-    return inferrer.concreteTypes.putIfAbsent(
-      node, () => new ContainerTypeMask(
-          inferrer.growableListType, node, outermostElement));
+    if (node.isConst()) {
+      // We only set the type once. We don't need to re-visit the children
+      // when re-analyzing the node.
+      return inferrer.concreteTypes.putIfAbsent(node, () {
+        ContainerTypeMask container = new ContainerTypeMask(
+            inferrer.constListType, node, outermostElement);
+        TypeMask elementType = new TypeMask.nonNullEmpty();
+        for (Node element in node.elements.nodes) {
+          elementType = computeLUB(elementType, visit(element), compiler);
+        }
+        container.elementType = elementType;
+        return container;
+      });
+    } else {
+      node.visitChildren(this);
+      return inferrer.concreteTypes.putIfAbsent(
+        node, () => new ContainerTypeMask(
+            inferrer.growableListType, node, outermostElement));
+    }
   }
 
   bool isThisOrSuper(Node node) => node.isThis() || node.isSuper();
@@ -1559,14 +1674,14 @@
           node.arguments.head);
     } else {
       // [: foo++ :] or [: foo += 1 :].
-      Selector constraint;
+      ArgumentsTypes operatorArguments = new ArgumentsTypes([rhsType], null);
+      CallSite constraint;
       if (!Elements.isLocal(element)) {
         // Record a constraint of the form [: field++ :], or [: field += 42 :].
-        constraint = operatorSelector;
+        constraint = new CallSite(operatorSelector, operatorArguments);
       }
       TypeMask getterType;
       TypeMask newType;
-      ArgumentsTypes operatorArguments = new ArgumentsTypes([rhsType], null);
       if (Elements.isStaticOrTopLevelField(element)) {
         Element getterElement = elements[node.selector];
         getterType =
@@ -1613,7 +1728,7 @@
                                  TypeMask receiverType,
                                  TypeMask rhsType,
                                  Node rhs) {
-    Selector constraint;
+    CallSite constraint;
     if (node.asSend() != null && !Elements.isLocal(element)) {
       // Recognize a constraint of the form [: field = other.field :].
       // Note that we check if the right hand side is a local to
@@ -1626,7 +1741,7 @@
           && !Elements.isLocal(elements[rhs])
           && send.selector.asIdentifier().source
                == node.asSend().selector.asIdentifier().source) {
-        constraint = elements.getSelector(rhs);
+        constraint = new CallSite(elements.getSelector(rhs), null);
       }
     }
     ArgumentsTypes arguments = new ArgumentsTypes([rhsType], null);
@@ -1697,7 +1812,8 @@
       return inferrer.concreteTypes.putIfAbsent(
           node, () => new ContainerTypeMask(
               inferrer.growableListType, node, outermostElement));
-    } else if (Elements.isFixedListConstructorCall(element, node, compiler)) {
+    } else if (Elements.isFixedListConstructorCall(element, node, compiler)
+        || Elements.isFilledListConstructorCall(element, node, compiler)) {
       return inferrer.concreteTypes.putIfAbsent(
           node, () => new ContainerTypeMask(
               inferrer.fixedListType, node, outermostElement));
@@ -1825,7 +1941,7 @@
                              Selector selector,
                              TypeMask receiver,
                              ArgumentsTypes arguments,
-                             [Selector constraint]) {
+                             [CallSite constraint]) {
     if (selector.mask != receiver) {
       selector = inferrer.isDynamicType(receiver)
           ? selector.asUntyped
@@ -1862,7 +1978,7 @@
   }
 
   void recordReturnType(TypeMask type) {
-    returnType = computeLUB(returnType, type, compiler);
+    returnType = inferrer.computeLubFor(returnType, type, analyzedElement);
   }
 
   TypeMask visitReturn(Return node) {
@@ -1901,7 +2017,7 @@
           ? inferrer.nullType
           : expression.accept(this));
     }
-    locals.seenReturn = true;
+    locals.seenReturnOrThrow = true;
     return inferrer.dynamicType;
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index e53cc0a..334b520 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -47,8 +47,11 @@
   bool get isEmpty;
   bool get isNullable;
   bool get isExact;
+
   bool get isUnion;
   bool get isContainer;
+  bool get isForwarding;
+  bool get isElement;
 
   bool containsOnlyInt(Compiler compiler);
   bool containsOnlyDouble(Compiler compiler);
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index d260746..6db7670 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -18,7 +18,9 @@
 
 part 'concrete_types_inferrer.dart';
 part 'container_type_mask.dart';
+part 'element_type_mask.dart';
 part 'flat_type_mask.dart';
+part 'forwarding_type_mask.dart';
 part 'type_mask.dart';
 part 'union_type_mask.dart';
 
diff --git a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
index 357486b..8f1a4ff 100644
--- a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
@@ -20,23 +20,23 @@
     return new UnionTypeMask._(disjoint);
   }
 
+  static TypeMask nonForwardingMask(mask) {
+    while (mask.isForwarding) mask = mask.forwardTo;
+    return mask;
+  }
+
   static void unionOfHelper(Iterable<TypeMask> masks,
                             List<FlatTypeMask> disjoint,
                             Compiler compiler) {
     for (TypeMask mask in masks) {
+      mask = nonForwardingMask(mask);
       if (mask.isUnion) {
         UnionTypeMask union = mask;
         unionOfHelper(union.disjointMasks, disjoint, compiler);
       } else if (mask.isEmpty && !mask.isNullable) {
         continue;
       } else {
-        FlatTypeMask flatMask;
-        if (mask.isContainer) {
-          ContainerTypeMask container = mask;
-          flatMask = container.asFlat;
-        } else {
-          flatMask = mask;
-        }
+        FlatTypeMask flatMask = mask;
         assert(flatMask.base == null
                || flatMask.base.element != compiler.dynamicClass);
         int inListIndex = -1;
@@ -146,7 +146,7 @@
   }
 
   TypeMask union(var other, Compiler compiler) {
-    if (other.isContainer) other = other.asFlat;
+    other = nonForwardingMask(other);
     if (!other.isUnion && disjointMasks.contains(other)) return this;
 
     List<FlatTypeMask> newList =
@@ -161,7 +161,7 @@
   }
 
   TypeMask intersection(var other, Compiler compiler) {
-    if (other.isContainer) other = other.asFlat;
+    other = nonForwardingMask(other);
     if (!other.isUnion && disjointMasks.contains(other)) return other;
 
     List<TypeMask> intersections = <TypeMask>[];
@@ -198,6 +198,8 @@
   bool get isExact => false;
   bool get isUnion => true;
   bool get isContainer => false;
+  bool get isForwarding => false;
+  bool get isElement => false;
 
   bool containsOnlyInt(Compiler compiler) => false;
   bool containsOnlyDouble(Compiler compiler) => false;
diff --git a/sdk/lib/_internal/compiler/implementation/universe/selector_map.dart b/sdk/lib/_internal/compiler/implementation/universe/selector_map.dart
deleted file mode 100644
index 29e705c..0000000
--- a/sdk/lib/_internal/compiler/implementation/universe/selector_map.dart
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of universe;
-
-class SelectorMap<T> {
-  final Compiler compiler;
-  final Map<SourceString, SelectorMapNode<T>> nodes =
-      new Map<SourceString, SelectorMapNode<T>>();
-  SelectorMap(this.compiler);
-
-  T operator [](Selector selector) {
-    SourceString name = selector.name;
-    SelectorMapNode node = nodes[name];
-    return (node != null)
-        ? node.lookup(selector)
-        : null;
-  }
-
-  void operator []=(Selector selector, T value) {
-    SourceString name = selector.name;
-    SelectorMapNode node = nodes.putIfAbsent(
-        name, () => new SelectorMapNode(name));
-    node.update(selector, value);
-  }
-
-  bool containsKey(Selector selector) {
-    SourceString name = selector.name;
-    SelectorMapNode node = nodes[name];
-    return (node != null)
-        ? node.containsKey(selector)
-        : false;
-  }
-
-  T remove(Selector selector) {
-    SourceString name = selector.name;
-    SelectorMapNode node = nodes[name];
-    return (node != null)
-        ? node.remove(selector)
-        : null;
-  }
-
-  /**
-   * Visits all mappings for selectors that may be used to invoke the
-   * given [member] element. If the [visit] function ever returns false,
-   * we abort the traversal early.
-   */
-  void visitMatching(Element member, bool visit(Selector selector, T value)) {
-    assert(member.isMember());
-    SourceString name = member.name;
-    SelectorMapNode node = nodes[name];
-    if (node != null) {
-      node.visitMatching(member, compiler, visit);
-    }
-  }
-}
-
-class SelectorMapNode<T> {
-  final SourceString name;
-  final Map<Selector, T> selectors = new Map<Selector, T>();
-
-  // We start caching which selectors match which elements when the
-  // number of different selectors exceed a threshold. This way we
-  // avoid lots of repeated calls to the Selector.applies method.
-  static const int MAX_SELECTORS_NO_CACHE = 8;
-  Map<Element, List<Selector>> cache;
-
-  SelectorMapNode(this.name);
-
-  T lookup(Selector selector) {
-    assert(selector.name == name);
-    return selectors[selector];
-  }
-
-  void update(Selector selector, T value) {
-    assert(selector.name == name);
-    bool existing = selectors.containsKey(selector);
-    selectors[selector] = value;
-    if (existing) return;
-    // The update has introduced a new selector in the map, so we need
-    // to consider if we should start caching. At the very least, we
-    // have to clear the cache because the new element may invalidate
-    // existing cache entries.
-    if (cache == null) {
-      if (selectors.length > MAX_SELECTORS_NO_CACHE) {
-        cache = new Map<Element, List<Selector>>();
-      }
-    } else if (!cache.isEmpty) {
-      cache.clear();
-    }
-  }
-
-  bool containsKey(Selector selector) {
-    assert(selector.name == name);
-    return selectors.containsKey(selector);
-  }
-
-  T remove(Selector selector) {
-    assert(selector.name == name);
-    if (!selectors.containsKey(selector)) return null;
-    if (cache != null && !cache.isEmpty) cache.clear();
-    return selectors.remove(selector);
-  }
-
-  void visitMatching(Element member, Compiler compiler,
-                     bool visit(Selector selector, T value)) {
-    assert(member.name == name);
-    Iterable<Selector> matching = computeMatching(member, compiler);
-    for (Selector selector in matching) {
-      if (!visit(selector, selectors[selector])) return;
-    }
-  }
-
-  Iterable<Selector> computeMatching(Element member, Compiler compiler) {
-    // Probe the cache if it exists. Do this before creating the
-    // matching iterable to cut down on the overhead for cache hits.
-    if (cache != null) {
-      List<Selector> cached = cache[member];
-      if (cached != null) return cached;
-    }
-    // Filter the selectors keys so we only have the ones that apply
-    // to the given member element.
-    Iterable<Selector> matching = selectors.keys.where(
-        (Selector selector) => selector.appliesUnnamed(member, compiler));
-    if (cache == null) return matching;
-    return cache[member] = matching.toList();
-  }
-}
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index ae3b54b..c366000 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -14,7 +14,6 @@
 import '../js/js.dart' as js;
 
 part 'function_set.dart';
-part 'selector_map.dart';
 part 'side_effects.dart';
 
 class Universe {
@@ -50,6 +49,20 @@
   final Set<Element> fieldSetters;
   final Set<DartType> isChecks;
 
+  /**
+   * Set of [:call:] methods in instantiated classes that use type variables
+   * in their signature.
+   */
+  final Set<Element> genericCallMethods;
+
+  /**
+   * Set of methods in instantiated classes that use type variables in their
+   * signature and have potentially been closurized.
+   */
+  final Set<Element> closurizedGenericMembers;
+
+  final Set<Element> closurizedMembers;
+
   bool usingFactoryWithTypeArguments = false;
 
   Universe() : instantiatedClasses = new Set<ClassElement>(),
@@ -60,7 +73,10 @@
                invokedSetters = new Map<SourceString, Set<Selector>>(),
                fieldGetters = new Set<Element>(),
                fieldSetters = new Set<Element>(),
-               isChecks = new Set<DartType>();
+               isChecks = new Set<DartType>(),
+               genericCallMethods = new Set<Element>(),
+               closurizedGenericMembers = new Set<Element>(),
+               closurizedMembers = new Set<Element>();
 
   bool hasMatchingSelector(Set<Selector> selectors,
                            Element member,
@@ -91,6 +107,15 @@
   bool hasFieldSetter(Element member, Compiler compiler) {
     return fieldSetters.contains(member);
   }
+
+  DartType registerIsCheck(DartType type, Compiler compiler) {
+    type = type.unalias(compiler);
+    // Even in checked mode, type annotations for return type and argument
+    // types do not imply type checks, so there should never be a check
+    // against the type variable of a typedef.
+    isChecks.add(type);
+    return type;
+  }
 }
 
 class SelectorKind {
diff --git a/sdk/lib/_internal/compiler/implementation/util/expensive_map.dart b/sdk/lib/_internal/compiler/implementation/util/expensive_map.dart
new file mode 100644
index 0000000..735284f
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/util/expensive_map.dart
@@ -0,0 +1,71 @@
+// 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.
+
+part of dart2js.util;
+
+/**
+ * The expensive map is a data structure useful for tracking down
+ * excessive memory usage due to large maps. It acts as an ordinary
+ * hash map, but it uses 10 times more memory (by default).
+ */
+class ExpensiveMap<K, V> implements LinkedHashMap<K, V> {
+
+  final List _maps;
+
+  ExpensiveMap([int copies = 10]) : _maps = new List(copies) {
+    assert(copies > 0);
+    for (int i = 0; i < _maps.length; i++) {
+      _maps[i] = new LinkedHashMap<K, V>();
+    }
+  }
+
+  int get length => _maps[0].length;
+  bool get isEmpty => _maps[0].isEmpty;
+  bool get isNotEmpty => _maps[0].isNotEmpty;
+
+  Iterable<K> get keys => _maps[0].keys;
+  Iterable<V> get values => _maps[0].values;
+
+  bool containsKey(K key) => _maps[0].containsKey(key);
+  bool containsValue(V value) => _maps[0].containsValue(value);
+
+  V operator[](K key) => _maps[0][key];
+
+  void forEach(void action(K key, V value)) {
+    _maps[0].forEach(action);
+  }
+
+  void operator[]=(K key, V value) {
+    for (int i = 0; i < _maps.length; i++) {
+      _maps[i][key] = value;
+    }
+  }
+
+  V putIfAbsent(K key, V ifAbsent()) {
+    if (containsKey(key)) return this[key];
+    V value = ifAbsent();
+    this[key] = value;
+    return value;
+  }
+
+  void addAll(Map<K, V> other) {
+    for (int i = 0; i < _maps.length; i++) {
+      _maps[i].addAll(other);
+    }
+  }
+
+  void remove(Object key) {
+    for (int i = 0; i < _maps.length; i++) {
+      _maps[i].remove(key);
+    }
+  }
+
+  void clear() {
+    for (int i = 0; i < _maps.length; i++) {
+      _maps[i].clear();
+    }
+  }
+
+  String toString() => "expensive(${_maps[0]}x${_maps.length})";
+}
diff --git a/sdk/lib/_internal/compiler/implementation/util/expensive_set.dart b/sdk/lib/_internal/compiler/implementation/util/expensive_set.dart
new file mode 100644
index 0000000..477eb4c
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/util/expensive_set.dart
@@ -0,0 +1,121 @@
+// 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.
+
+part of dart2js.util;
+
+/**
+ * The expensive set is a data structure useful for tracking down
+ * excessive memory usage due to large sets. It acts as an ordinary
+ * hash set, but it uses 10 times more memory (by default).
+ */
+class ExpensiveSet<E> extends IterableBase<E> implements LinkedHashSet<E> {
+
+  final List _sets;
+
+  ExpensiveSet([int copies = 10]) : _sets = new List(copies) {
+    assert(copies > 0);
+    for (int i = 0; i < _sets.length; i++) {
+      _sets[i] = new LinkedHashSet<E>();
+    }
+  }
+
+  int get length => _sets[0].length;
+  bool get isEmpty => _sets[0].isEmpty;
+  bool get isNotEmpty => _sets[0].isNotEmpty;
+
+  Iterator<E> get iterator => _sets[0].iterator;
+
+  bool contains(Object object) => _sets[0].contains(object);
+
+  void forEach(void action(E element)) {
+    _sets[0].forEach(action);
+  }
+
+  void add(E element) {
+    for (int i = 0; i < _sets.length; i++) {
+      _sets[i].add(element);
+    }
+  }
+
+  void addAll(Iterable<E> objects) {
+    for (E each in objects) {
+      add(each);
+    }
+  }
+
+  bool remove(Object object) {
+    bool result = _sets[0].remove(object);
+    for (int i = 1; i < _sets.length; i++) {
+      _sets[i].remove(object);
+    }
+    return result;
+  }
+
+  void clear() {
+    for (int i = 0; i < _sets.length; i++) {
+      _sets[i].clear();
+    }
+  }
+
+  void removeAll(Iterable<Object> objectsToRemove) {
+    for (var each in objectsToRemove) {
+      remove(each);
+    }
+  }
+
+  void removeWhere(bool test(E element)) {
+    removeAll(this.toList().where((e) => test(e)));
+  }
+
+  void retainWhere(bool test(E element)) {
+    removeAll(toList().where((e) => !test(e)));
+  }
+
+  bool containsAll(Iterable<Object> other) {
+    for (Object object in other) {
+      if (!this.contains(object)) return false;
+    }
+    return true;
+  }
+
+  Set _newSet() => new ExpensiveSet(_sets.length);
+
+  Set<E> intersection(Set<Object> other) {
+    Set<E> result = _newSet();
+    if (other.length < this.length) {
+      for (var element in other) {
+        if (this.contains(element)) result.add(element);
+      }
+    } else {
+      for (E element in this) {
+        if (other.contains(element)) result.add(element);
+      }
+    }
+    return result;
+  }
+
+  Set<E> union(Set<E> other) {
+    return _newSet()..addAll(this)..addAll(other);
+  }
+
+  Set<E> difference(Set<E> other) {
+    Set<E> result = _newSet();
+    for (E element in this) {
+      if (!other.contains(element)) result.add(element);
+    }
+    return result;
+  }
+
+  void retainAll(Iterable objectsToRetain) {
+    Set retainSet;
+    if (objectsToRetain is Set) {
+      retainSet = objectsToRetain;
+    } else {
+      retainSet = objectsToRetain.toSet();
+    }
+    retainWhere(retainSet.contains);
+  }
+
+  String toString() => "expensive(${_sets[0]}x${_sets.length})";
+}
diff --git a/sdk/lib/_internal/compiler/implementation/util/link.dart b/sdk/lib/_internal/compiler/implementation/util/link.dart
index 29bc4c6..f46af2d 100644
--- a/sdk/lib/_internal/compiler/implementation/util/link.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/link.dart
@@ -2,7 +2,7 @@
 // for 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 org_dartlang_compiler_util;
+part of dart2js.util;
 
 class Link<T> {
   T get head => null;
@@ -107,7 +107,12 @@
 abstract class LinkBuilder<T> {
   factory LinkBuilder() = LinkBuilderImplementation;
 
-  Link<T> toLink();
+  /**
+   * Prepends all elements added to the builder to [tail]. The resulting list is
+   * returned and the builder is cleared.
+   */
+  Link<T> toLink([Link<T> tail = const Link()]);
+
   void addLast(T t);
 
   final int length;
diff --git a/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart b/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart
index 4b0a618..6743738 100644
--- a/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart
@@ -110,9 +110,9 @@
 
   LinkBuilderImplementation();
 
-  Link<T> toLink() {
-    if (head == null) return const Link();
-    lastLink.tail = const Link();
+  Link<T> toLink([Link<T> tail = const Link()]) {
+    if (head == null) return tail;
+    lastLink.tail = tail;
     Link<T> link = head;
     lastLink = null;
     head = null;
diff --git a/sdk/lib/_internal/compiler/implementation/util/util.dart b/sdk/lib/_internal/compiler/implementation/util/util.dart
index c9c0e66..94a0ce0 100644
--- a/sdk/lib/_internal/compiler/implementation/util/util.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/util.dart
@@ -2,13 +2,15 @@
 // for 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 org_dartlang_compiler_util;
+library dart2js.util;
 
 import "dart:collection";
 import 'util_implementation.dart';
 import 'characters.dart';
 
 part 'link.dart';
+part 'expensive_map.dart';
+part 'expensive_set.dart';
 
 /**
  * Tagging interface for classes from which source spans can be generated.
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 5425bd1..8f9b9cb 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -26,6 +26,8 @@
       'additional argument');
   static const NAMED_ARGUMENT_NOT_FOUND = const MessageKind(
       "no named argument '#{argumentName}' found on method");
+  static const MEMBER_NOT_FOUND = const MessageKind(
+      'no member named #{memberName} in class #{className}');
   static const METHOD_NOT_FOUND = const MessageKind(
       'no method named #{memberName} in class #{className}');
   static const OPERATOR_NOT_FOUND = const MessageKind(
@@ -163,6 +165,8 @@
   static const TYPE_VARIABLE_WITHIN_STATIC_MEMBER = const MessageKind(
       'cannot refer to type variable #{typeVariableName} '
       'within a static member');
+  static const TYPE_VARIABLE_IN_CONSTANT = const MessageKind(
+      'Error: cannot refer to type variable in constant');
 
   static const INVALID_USE_OF_SUPER = const MessageKind(
       'super not allowed here');
diff --git a/sdk/lib/_internal/dartdoc/bin/dartdoc.dart b/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
index c0fdf6e..2e42264 100644
--- a/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
@@ -207,14 +207,14 @@
 
   final entrypoints = <Uri>[];
   try {
-    final option = argParser.parse(args);
+    final option = argParser.parse(args, allowTrailingOptions: true);
 
     // This checks to see if the root of all entrypoints is the same.
     // If it is not, then we display a warning, as package imports might fail.
     var entrypointRoot;
     for (final entrypoint in option.rest) {
       var uri = Uri.parse(entrypoint);
-      if (uri.scheme == '') uri = pathToFileUri(entrypoint);
+      if (uri.scheme == '') uri = path.toUri(entrypoint);
       entrypoints.add(uri);
 
       if (uri.scheme != 'file') continue;
@@ -274,7 +274,7 @@
       orElse: () => null);
   if (fileEntrypoint == null) return;
 
-  var script = path.normalize(path.absolute(fileUriToPath(fileEntrypoint)));
+  var script = path.normalize(path.absolute(path.fromUri(fileEntrypoint)));
   var dir = path.join(path.dirname(script), 'packages/');
   if (new Directory(dir).existsSync()) return dir;
 
diff --git a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
index 7d5eba0..0274875 100644
--- a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
@@ -71,7 +71,7 @@
 // TODO(johnniwinther): Convert to final (lazily initialized) variables when
 // the feature is supported.
 Path get scriptDir =>
-    new Path(new Options().script).directoryPath;
+    new Path(Platform.script).directoryPath;
 
 /**
  * Deletes and recreates the output directory at [path] if it exists.
@@ -434,7 +434,7 @@
     _exports = new ExportMap.parse(libraryList, packageRoot);
     var librariesToAnalyze = _exports.allExportedFiles.toList();
     librariesToAnalyze.addAll(libraryList.map((uri) {
-      if (uri.scheme == 'file') return fileUriToPath(uri);
+      if (uri.scheme == 'file') return pathos.fromUri(uri);
       // dart2js takes "dart:*" URIs as Path objects for some reason.
       return uri.toString();
     }));
@@ -771,11 +771,11 @@
   /// Whether dartdoc is running from within the Dart SDK or the
   /// Dart source repository.
   bool get runningFromSdk =>
-    pathos.extension(new Options().script) == '.snapshot';
+    pathos.extension(Platform.script) == '.snapshot';
 
   /// Gets the path to the root directory of the SDK.
   String get sdkDir =>
-    pathos.dirname(pathos.dirname(new Options().executable));
+    pathos.dirname(pathos.dirname(Platform.executable));
 
   /// Gets the path to the dartdoc directory normalized for running in different
   /// places.
@@ -799,9 +799,8 @@
         '''library client;
         import 'dart:html';
         import 'dart:json';
-        import r'${pathToFileUri(
-          pathos.join(clientDir, 'client-shared.dart'))}';
-        import r'${pathToFileUri(pathos.join(clientDir, 'dropdown.dart'))}';
+        import r'${pathos.toUri(pathos.join(clientDir, 'client-shared.dart'))}';
+        import r'${pathos.toUri(pathos.join(clientDir, 'dropdown.dart'))}';
 
         main() {
           setup();
diff --git a/sdk/lib/_internal/dartdoc/lib/src/dartdoc/utils.dart b/sdk/lib/_internal/dartdoc/lib/src/dartdoc/utils.dart
index 4b95669..425deaf 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/dartdoc/utils.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/dartdoc/utils.dart
@@ -96,7 +96,7 @@
  * If a URI cannot be converted, this will return `null`.
  */
 String importUriToPath(Uri uri, {String basePath, String packageRoot}) {
-  if (uri.scheme == 'file') return fileUriToPath(uri);
+  if (uri.scheme == 'file') return pathos.fromUri(uri);
 
   if (basePath != null && uri.scheme == '') {
     return pathos.normalize(pathos.absolute(pathos.join(basePath, uri.path)));
@@ -111,36 +111,6 @@
   return null;
 }
 
-/** Converts a `file:` [Uri] to a local path string. */
-String fileUriToPath(Uri uri) {
-  if (uri.scheme != 'file') {
-    throw new ArgumentError("Uri $uri must have scheme 'file:'.");
-  }
-  if (Platform.operatingSystem != 'windows') return uri.path;
-  if (uri.path.startsWith("/")) {
-    // Drive-letter paths look like "file:///C:/path/to/file". The replaceFirst
-    // removes the extra initial slash.
-    return uri.path.replaceFirst("/", "").replaceAll("/", "\\");
-  } else {
-    // Network paths look like "file://hostname/path/to/file".
-    return "\\\\${uri.path.replaceAll("/", "\\")}";
-  }
-}
-
-/** Converts a local path string to a `file:` [Uri]. */
-Uri pathToFileUri(String pathString) {
-  pathString = pathos.absolute(pathString);
-  if (Platform.operatingSystem != 'windows') {
-    return Uri.parse('file://$pathString');
-  } else if (pathos.rootPrefix(pathString).startsWith('\\\\')) {
-    // Network paths become "file://hostname/path/to/file".
-    return Uri.parse('file:${pathString.replaceAll("\\", "/")}');
-  } else {
-    // Drive-letter paths become "file:///C:/path/to/file".
-    return Uri.parse('file:///${pathString.replaceAll("\\", "/")}');
-  }
-}
-
 /**
  * If [map] contains an [Export] under [key], this merges that with [export].
  * Otherwise, it sets [key] to [export].
diff --git a/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart b/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart
index 60eb3ac..d3936c5 100644
--- a/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart
+++ b/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart
@@ -194,7 +194,7 @@
 
 /// The path to the root directory of the dartdoc entrypoint.
 String get _dartdocDir {
-  var dir = path.absolute(new Options().script);
+  var dir = path.absolute(Platform.script);
   while (path.basename(dir) != 'dartdoc') {
     if (!path.absolute(dir).contains('dartdoc') || dir == path.dirname(dir)) {
       fail('Unable to find root dartdoc directory.');
@@ -217,7 +217,7 @@
   // is in the build output directory. We can find that directory relative to
   // the Dart executable, but that could be in one of two places: in
   // "$BUILD/dart" or "$BUILD/dart-sdk/bin/dart".
-  var executableDir = path.dirname(new Options().executable);
+  var executableDir = path.dirname(Platform.executable);
   if (new Directory(path.join(executableDir, 'dart-sdk')).existsSync()) {
     // The executable is in "$BUILD/dart".
     return path.absolute(path.join(executableDir, 'packages'));
@@ -230,7 +230,7 @@
 /// Runs dartdoc with the libraryPaths provided, and completes to dartdoc's
 /// ProcessResult.
 Future<ProcessResult> _runDartdoc(List<String> libraryPaths) {
-  var dartBin = new Options().executable;
+  var dartBin = Platform.executable;
 
   var dartdoc = path.join(_dartdocDir, 'bin/dartdoc.dart');
 
diff --git a/sdk/lib/_internal/dartdoc/test/export_map_test.dart b/sdk/lib/_internal/dartdoc/test/export_map_test.dart
index 7d271d8..badb755 100644
--- a/sdk/lib/_internal/dartdoc/test/export_map_test.dart
+++ b/sdk/lib/_internal/dartdoc/test/export_map_test.dart
@@ -373,8 +373,7 @@
 
 ExportMap parse(List<String> libraries) {
   return new ExportMap.parse(
-      libraries.map(libPath)
-          .map(pathToFileUri),
+      libraries.map(libPath).map(pathos.toUri),
       pathos.join(tempDir, 'packages'));
 }
 
diff --git a/sdk/lib/_internal/lib/collection_patch.dart b/sdk/lib/_internal/lib/collection_patch.dart
index 803c97e..3fb0f45 100644
--- a/sdk/lib/_internal/lib/collection_patch.dart
+++ b/sdk/lib/_internal/lib/collection_patch.dart
@@ -40,7 +40,7 @@
     return keys.map((each) => this[each]);
   }
 
-  patch bool containsKey(K key) {
+  patch bool containsKey(Object key) {
     if (_isStringKey(key)) {
       var strings = _strings;
       return (strings == null) ? false : _hasTableEntry(strings, key);
@@ -55,7 +55,7 @@
     }
   }
 
-  patch bool containsValue(V value) {
+  patch bool containsValue(Object value) {
     return _computeKeys().any((each) => this[each] == value);
   }
 
@@ -65,7 +65,7 @@
     });
   }
 
-  patch V operator[](K key) {
+  patch V operator[](Object key) {
     if (_isStringKey(key)) {
       var strings = _strings;
       return (strings == null) ? null : _getTableEntry(strings, key);
@@ -119,7 +119,7 @@
     return value;
   }
 
-  patch V remove(K key) {
+  patch V remove(Object key) {
     if (_isStringKey(key)) {
       return _removeHashTableEntry(_strings, key);
     } else if (_isNumericKey(key)) {
@@ -319,7 +319,7 @@
     return new HashMapKeyIterator<E>(_map, _map._computeKeys());
   }
 
-  bool contains(E element) {
+  bool contains(Object element) {
     return _map.containsKey(element);
   }
 
@@ -403,7 +403,7 @@
     return keys.map((each) => this[each]);
   }
 
-  patch bool containsKey(K key) {
+  patch bool containsKey(Object key) {
     if (_isStringKey(key)) {
       var strings = _strings;
       if (strings == null) return false;
@@ -422,7 +422,7 @@
     }
   }
 
-  patch bool containsValue(V value) {
+  patch bool containsValue(Object value) {
     return keys.any((each) => this[each] == value);
   }
 
@@ -432,7 +432,7 @@
     });
   }
 
-  patch V operator[](K key) {
+  patch V operator[](Object key) {
     if (_isStringKey(key)) {
       var strings = _strings;
       if (strings == null) return null;
@@ -491,7 +491,7 @@
     return value;
   }
 
-  patch V remove(K key) {
+  patch V remove(Object key) {
     if (_isStringKey(key)) {
       return _removeHashTableEntry(_strings, key);
     } else if (_isNumericKey(key)) {
@@ -673,7 +673,7 @@
     return new LinkedHashMapKeyIterator<E>(_map, _map._modifications);
   }
 
-  bool contains(E element) {
+  bool contains(Object element) {
     return _map.containsKey(element);
   }
 
@@ -819,7 +819,7 @@
     }
   }
 
-  patch void removeAll(Iterable objectsToRemove) {
+  patch void removeAll(Iterable<Object> objectsToRemove) {
     for (var each in objectsToRemove) {
       remove(each);
     }
diff --git a/sdk/lib/_internal/lib/foreign_helper.dart b/sdk/lib/_internal/lib/foreign_helper.dart
index 3cfe86a..55e99a1 100644
--- a/sdk/lib/_internal/lib/foreign_helper.dart
+++ b/sdk/lib/_internal/lib/foreign_helper.dart
@@ -34,10 +34,6 @@
  * [typeDescription] has several extensions to help describe the behavior more
  * accurately.  In addition to the union type already described:
  *
- *  + `=List` is the JavaScript array type.  This is more precise than `List`,
- *     which includes about fifty DOM types that also implement the List
- *     interface.
- *
  *  + `=Object` is a plain JavaScript object.  Some DOM methods return instances
  *     that have no corresponing Dart type (e.g. cross-frame documents),
  *     `=Object` can be used to describe these untyped' values.
@@ -47,9 +43,6 @@
  *
  * Examples:
  *
- *     // Create a JavaScript Array.
- *     List a = JS('=List', 'new Array(#)', length);
- *
  *     // Parent window might be an opaque cross-frame window.
  *     var thing = JS('=Object|Window', '#.parent', myWindow);
  *
@@ -161,6 +154,9 @@
 /// Returns the name of the class `Object` in the generated code.
 String JS_OBJECT_CLASS_NAME() {}
 
+/// Returns the name of the class `Function` in the generated code.
+String JS_FUNCTION_CLASS_NAME() {}
+
 /**
  * Returns the field name used for determining if an object or its
  * interceptor has JavaScript indexing behavior.
@@ -171,3 +167,44 @@
  * Returns the object corresponding to Namer.CURRENT_ISOLATE.
  */
 JS_CURRENT_ISOLATE() {}
+
+/// Returns the name used for generated function types on classes and methods.
+String JS_SIGNATURE_NAME() {}
+
+/// Returns the name used to tag function type representations in JavaScript.
+String JS_FUNCTION_TYPE_TAG() {}
+
+/**
+ * Returns the name used to tag void return in function type representations
+ * in JavaScript.
+ */
+String JS_FUNCTION_TYPE_VOID_RETURN_TAG() {}
+
+/**
+ * Returns the name used to tag return types in function type representations
+ * in JavaScript.
+ */
+String JS_FUNCTION_TYPE_RETURN_TYPE_TAG() {}
+
+/**
+ * Returns the name used to tag required parameters in function type
+ * representations in JavaScript.
+ */
+String JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG() {}
+
+/**
+ * Returns the name used to tag optional parameters in function type
+ * representations in JavaScript.
+ */
+String JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG() {}
+
+/**
+ * Returns the name used to tag named parameters in function type
+ * representations in JavaScript.
+ */
+String JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG() {}
+
+/**
+ * Returns the global object, usually called encoded as [: $ :].
+ */
+JS_GLOBAL_OBJECT() {}
diff --git a/sdk/lib/_internal/lib/io_patch.dart b/sdk/lib/_internal/lib/io_patch.dart
index 25df301..4967d94 100644
--- a/sdk/lib/_internal/lib/io_patch.dart
+++ b/sdk/lib/_internal/lib/io_patch.dart
@@ -168,6 +168,9 @@
   patch static _environment() {
     throw new UnsupportedError("Platform._environment");
   }
+  patch static String _version() {
+    throw new UnsupportedError("Platform._version");
+  }
 }
 
 patch class _ProcessUtils {
@@ -191,6 +194,7 @@
       List<String> arguments,
       {String workingDirectory,
        Map<String, String> environment,
+       bool includeParentEnvironment: true,
        bool runInShell: false}) {
     throw new UnsupportedError("Process.start");
   }
@@ -200,6 +204,7 @@
       List<String> arguments,
       {String workingDirectory,
        Map<String, String> environment,
+       bool includeParentEnvironment: true,
        bool runInShell: false,
        Encoding stdoutEncoding: Encoding.SYSTEM,
        Encoding stderrEncoding: Encoding.SYSTEM}) {
@@ -226,6 +231,15 @@
   }
 }
 
+patch class NetworkInterface {
+  patch static Future<List<NetworkInterface>> list({
+      bool includeLoopback: false,
+      bool includeLinkLocal: false,
+      InternetAddressType type: InternetAddressType.ANY}) {
+    throw new UnsupportedError("NetworkInterface.list");
+  }
+}
+
 patch class RawServerSocket {
   patch static Future<RawServerSocket> bind(address,
                                             int port,
@@ -272,6 +286,9 @@
   patch factory _SecureFilter() {
     throw new UnsupportedError("_SecureFilter._SecureFilter");
   }
+  patch static SendPort _newServicePort() {
+    throw new UnsupportedError("_SecureFilter._newServicePort");
+  }
 }
 
 patch class _StdIOUtils {
@@ -306,9 +323,3 @@
     throw new UnsupportedError("newZLibInflateFilter");
   }
 }
-
-patch class _OptionsImpl {
-  patch String get version {
-    throw new UnsupportedError("_OptionsImpl.version");
-  }
-}
diff --git a/sdk/lib/_internal/lib/isolate_helper.dart b/sdk/lib/_internal/lib/isolate_helper.dart
index 3743ad0..47df338 100644
--- a/sdk/lib/_internal/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/lib/isolate_helper.dart
@@ -16,6 +16,7 @@
                                    JS_CURRENT_ISOLATE,
                                    JS_SET_CURRENT_ISOLATE,
                                    IsolateContext;
+import 'dart:_interceptors' show JSExtendableArray;
 
 ReceivePort lazyPort;
 
@@ -455,14 +456,14 @@
                  r'new RegExp("^ *at [^(]*\\((.*):[0-9]*:[0-9]*\\)$", "m")');
 
 
-    matches = JS('=List|Null', '#.match(#)', stack, pattern);
+    matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
     if (matches != null) return JS('String', '#[1]', matches);
 
     // This pattern matches Firefox stack traces that look like this:
     // methodName@URI:LINE
     pattern = JS('', r'new RegExp("^[^@]*@(.*):[0-9]*$", "m")');
 
-    matches = JS('=List|Null', '#.match(#)', stack, pattern);
+    matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
     if (matches != null) return JS('String', '#[1]', matches);
 
     throw new UnsupportedError('Cannot extract URI from "$stack"');
diff --git a/sdk/lib/_internal/lib/js_array.dart b/sdk/lib/_internal/lib/js_array.dart
index 40ce9fa..d3f3551 100644
--- a/sdk/lib/_internal/lib/js_array.dart
+++ b/sdk/lib/_internal/lib/js_array.dart
@@ -143,11 +143,11 @@
     return IterableMixinWorkaround.fold(this, initialValue, combine);
   }
 
-  E firstWhere(bool test(E value), {E orElse()}) {
+  dynamic firstWhere(bool test(E value), {Object orElse()}) {
     return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  E lastWhere(bool test(E value), {E orElse()}) {
+  dynamic lastWhere(bool test(E value), {Object orElse()}) {
     return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
@@ -175,7 +175,7 @@
     }
     // TODO(ngeoffray): Parameterize the return value.
     if (start == end) return [];
-    return JS('=List', r'#.slice(#, #)', this, start, end);
+    return JS('JSExtendableArray', r'#.slice(#, #)', this, start, end);
   }
 
 
@@ -242,17 +242,17 @@
     IterableMixinWorkaround.sortList(this, compare);
   }
 
-  int indexOf(E element, [int start = 0]) {
+  int indexOf(Object element, [int start = 0]) {
     return IterableMixinWorkaround.indexOfList(this, element, start);
   }
 
-  int lastIndexOf(E element, [int start]) {
+  int lastIndexOf(Object element, [int start]) {
     return IterableMixinWorkaround.lastIndexOfList(this, element, start);
   }
 
-  bool contains(E other) {
+  bool contains(Object other) {
     for (int i = 0; i < length; i++) {
-      if (other == this[i]) return true;
+      if (this[i] == other) return true;
     }
     return false;
   }
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index cd4e627..fadb984 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -11,13 +11,24 @@
                                    JS_CURRENT_ISOLATE,
                                    JS_CURRENT_ISOLATE_CONTEXT,
                                    JS_DART_OBJECT_CONSTRUCTOR,
+                                   JS_FUNCTION_CLASS_NAME,
                                    JS_IS_INDEXABLE_FIELD_NAME,
                                    JS_OBJECT_CLASS_NAME,
                                    JS_OPERATOR_AS_PREFIX,
                                    JS_OPERATOR_IS_PREFIX,
+                                   JS_GLOBAL_OBJECT,
+                                   JS_SIGNATURE_NAME,
+                                   JS_HAS_EQUALS,
+                                   JS_FUNCTION_TYPE_TAG,
+                                   JS_FUNCTION_TYPE_VOID_RETURN_TAG,
+                                   JS_FUNCTION_TYPE_RETURN_TYPE_TAG,
+                                   JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG,
+                                   JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG,
+                                   JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG,
                                    RAW_DART_FUNCTION_REF;
 import 'dart:_interceptors';
-import "dart:_collection-dev" as _symbol_dev;
+import 'dart:_collection-dev' as _symbol_dev;
+import 'dart:_js_names' show mangledNames;
 
 part 'constant_map.dart';
 part 'native_helper.dart';
@@ -25,10 +36,6 @@
 part 'string_helper.dart';
 part 'js_rti.dart';
 
-bool isJsArray(var value) {
-  return value != null && JS('bool', r'(#.constructor === Array)', value);
-}
-
 bool isJsIndexable(var object, var record) {
   if (record != null) {
     var result = dispatchRecordIndexability(record);
@@ -56,8 +63,18 @@
   return res;
 }
 
-createInvocationMirror(name, internalName, type, arguments, argumentNames) {
-  return new JSInvocationMirror(new _symbol_dev.Symbol.unvalidated(name),
+createInvocationMirror(String name, internalName, type, arguments,
+                       argumentNames) {
+  return new JSInvocationMirror(name,
+                                internalName,
+                                type,
+                                arguments,
+                                argumentNames);
+}
+
+createUnmangledInvocationMirror(Symbol symbol, internalName, type, arguments,
+                                argumentNames) {
+  return new JSInvocationMirror(symbol,
                                 internalName,
                                 type,
                                 arguments,
@@ -69,7 +86,9 @@
   static const GETTER = 1;
   static const SETTER = 2;
 
-  final Symbol memberName;
+  /// When [_memberName] is a String, it holds the mangled name of this
+  /// invocation.  When it is a Symbol, it holds the unmangled name.
+  var /* String or Symbol */ _memberName;
   final String _internalName;
   final int _kind;
   final List _arguments;
@@ -77,12 +96,23 @@
   /** Map from argument name to index in _arguments. */
   Map<String,dynamic> _namedIndices = null;
 
-  JSInvocationMirror(this.memberName,
+  JSInvocationMirror(this._memberName,
                      this._internalName,
                      this._kind,
                      this._arguments,
                      this._namedArgumentNames);
 
+  Symbol get memberName {
+    if (_memberName is Symbol) return _memberName;
+    String name = _memberName;
+    String unmangledName = mangledNames[name];
+    if (unmangledName != null) {
+      name = unmangledName.split(':')[0];
+    }
+    _memberName = new _symbol_dev.Symbol.unvalidated(name);
+    return _memberName;
+  }
+
   bool get isMethod => _kind == METHOD;
   bool get isGetter => _kind == GETTER;
   bool get isSetter => _kind == SETTER;
@@ -121,7 +151,7 @@
     // to be a JavaScript object with intercepted names as property
     // instead of a JavaScript array.
     if (JS('int', '#.indexOf(#)', interceptedNames, name) == -1) {
-      if (!isJsArray(arguments)) arguments = new List.from(arguments);
+      if (arguments is! JSArray) arguments = new List.from(arguments);
     } else {
       arguments = [object]..addAll(arguments);
       receiver = interceptor;
@@ -186,7 +216,7 @@
     JS('void', 'throw "Unable to print message: " + String(#)', string);
   }
 
-  static void _throwFormatException(String string) {
+  static _throwFormatException(String string) {
     throw new FormatException(string);
   }
 
@@ -196,7 +226,7 @@
     if (handleError == null) handleError = _throwFormatException;
 
     checkString(source);
-    var match = JS('=List|Null',
+    var match = JS('JSExtendableArray|Null',
         r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i.exec(#)',
         source);
     int digitsIndex = 1;
@@ -319,11 +349,11 @@
   }
 
   static List newGrowableList(length) {
-    return JS('=List', r'new Array(#)', length);
+    return JS('JSExtendableArray', r'new Array(#)', length);
   }
 
   static List newFixedList(length) {
-    var result = JS('=List', r'new Array(#)', length);
+    var result = JS('JSFixedArray', r'new Array(#)', length);
     JS('void', r'#.fixed$length = #', result, true);
     return result;
   }
@@ -352,7 +382,7 @@
       if (end <= kMaxApply) {
         subarray = array;
       } else {
-        subarray = JS('=List', r'#.slice(#, #)', array,
+        subarray = JS('JSExtendableArray', r'#.slice(#, #)', array,
                       i, i + kMaxApply < end ? i + kMaxApply : end);
       }
       result = JS('String', '# + String.fromCharCode.apply(#, #)',
@@ -566,7 +596,7 @@
     return JS('var', '#.apply(#, #)', jsFunction, function, arguments);
   }
 
-  static getConstructor(String className) {
+  static getConstructorOrInterceptor(String className) {
     // TODO(ahe): Generalize this and improve test coverage of
     // reflecting on intercepted classes.
     if (JS('bool', '# == "String"', className)) return const JSString();
@@ -1022,9 +1052,6 @@
  * one or more types, separated by vertical bars `|`.  There are some special
  * names:
  *
- * * `=List`. This means 'exactly List', which is the JavaScript Array
- *   implementation of [List] and no other implementation.
- *
  * * `=Object`. This means 'exactly Object', which is a plain JavaScript object
  *   with properties and none of the subtypes of Object.
  *
@@ -1059,11 +1086,11 @@
  *
  * Example: IndexedDB keys are numbers, strings and JavaScript Arrays of keys.
  *
- *     @Returns('String|num|=List')
+ *     @Returns('String|num|JSExtendableArray')
  *     dynamic key;
  *
  *     // Equivalent:
- *     @Returns('String') @Returns('num') @Returns('=List')
+ *     @Returns('String') @Returns('num') @Returns('JSExtendableArray')
  *     dynamic key;
  */
 class Returns {
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index 59b8355..d904246 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -16,27 +16,23 @@
     Null,
     Primitives,
     RuntimeError,
-    createInvocationMirror;
-import 'dart:_interceptors' show Interceptor;
+    createUnmangledInvocationMirror;
+import 'dart:_interceptors' show Interceptor, JSExtendableArray;
+import 'dart:_js_names';
 
-/// No-op method that is called to inform the compiler that
-/// tree-shaking needs to be disabled.
+/// No-op method that is called to inform the compiler that tree-shaking needs
+/// to be disabled.
 disableTreeShaking() => preserveNames();
 
-/// No-op method that is called to inform the compiler that unmangled
-/// named must be preserved.
-preserveNames() {}
+/// No-op method that is called to inform the compiler that metadata must be
+/// preserved at runtime.
+preserveMetadata() {}
 
 String getName(Symbol symbol) {
   preserveNames();
   return n(symbol);
 }
 
-final Map<String, String> mangledNames = JsMirrorSystem.computeMangledNames();
-
-final Map<String, String> reflectiveNames =
-    JsMirrorSystem.computeReflectiveNames();
-
 class JsMirrorSystem implements MirrorSystem {
   TypeMirror get dynamicType => _dynamicType;
   TypeMirror get voidType => _voidType;
@@ -48,6 +44,16 @@
   static final Map<String, List<LibraryMirror>> librariesByName =
       computeLibrariesByName();
 
+  Map<Uri, LibraryMirror> get libraries {
+    Map<Uri, LibraryMirror> result = new Map<Uri, LibraryMirror>();
+    for (List<LibraryMirror> list in librariesByName.values) {
+      for (LibraryMirror library in list) {
+        result[library.uri] = library;
+      }
+    }
+    return result;
+  }
+
   Iterable<LibraryMirror> findLibrary(Symbol libraryName) {
     return new List<LibraryMirror>.from(librariesByName[n(libraryName)]);
   }
@@ -55,7 +61,7 @@
   static Map<String, List<LibraryMirror>> computeLibrariesByName() {
     disableTreeShaking();
     var result = new Map<String, List<LibraryMirror>>();
-    var jsLibraries = JS('=List|Null', 'init.libraries');
+    var jsLibraries = JS('JSExtendableArray|Null', 'init.libraries');
     if (jsLibraries == null) return result;
     for (List data in jsLibraries) {
       String name = data[0];
@@ -71,26 +77,6 @@
     }
     return result;
   }
-
-  static Map<String, String> computeMangledNames() {
-    disableTreeShaking();
-    var mangledNames = JS('', 'init.mangledNames');
-    var keys = extractKeys(mangledNames);
-    var result = <String, String>{};
-    for (String key in keys) {
-      result[key] = JS('String', '#[#]', mangledNames, key);
-    }
-    return result;
-  }
-
-  static Map<String, String> computeReflectiveNames() {
-    disableTreeShaking();
-    var result = <String, String>{};
-    mangledNames.forEach((String mangledName, String reflectiveName) {
-      result[reflectiveName] = mangledName;
-    });
-    return result;
-  }
 }
 
 abstract class JsMirror {
@@ -127,6 +113,7 @@
   final List<String> _classes;
   final List<String> _functions;
   final List _metadata;
+  List<JsMethodMirror> _cachedFunctionMirrors;
 
   JsLibraryMirror(Symbol simpleName,
                  this.uri,
@@ -142,9 +129,8 @@
   Map<Symbol, ClassMirror> get classes {
     var result = new Map<Symbol, ClassMirror>();
     for (String className in _classes) {
-      Symbol symbol = s(className);
-      JsClassMirror cls = reflectClassByName(symbol);
-      result[symbol] = cls;
+      JsClassMirror cls = reflectClassByMangledName(className);
+      result[cls.simpleName] = cls;
       cls._owner = this;
     }
     return result;
@@ -161,25 +147,42 @@
     return reflect(JS('', '#[#]', JS_CURRENT_ISOLATE(), n(fieldName)));
   }
 
-  Map<Symbol, MethodMirror> get functions {
-    var result = new Map<Symbol, MethodMirror>();
+  List<JsMethodMirror> get _functionMirrors {
+    if (_cachedFunctionMirrors != null) return _cachedFunctionMirrors;
+    var result = new List<JsMethodMirror>(_functions.length);
     for (int i = 0; i < _functions.length; i++) {
       String name = _functions[i];
-      Symbol symbol = s(name);
+      String unmangledName = mangledGlobalNames[name];
+      if (unmangledName == null) unmangledName = name;
       int parameterCount = null; // TODO(ahe): Compute this.
-      bool isStatic = true; // Top-level functions are static.
       bool isSetter = false; // TODO(ahe): Compute this.
       bool isGetter = false; // TODO(ahe): Compute this.
+      bool isConstructor = unmangledName.startsWith('new ');
+      bool isStatic = true && !isConstructor; // Top-level functions are
+                                              // static, but constructors are
+                                              // not.
+      if (isConstructor) {
+        unmangledName = unmangledName.substring(4).replaceAll(r'$', '.');
+      }
+      unmangledName = unmangledName.split(':')[0];
+      Symbol symbol = s(unmangledName);
       JsMethodMirror mirror =
           // TODO(ahe): Create accessor for accessing $.  It is also
           // used in js_helper.
           new JsMethodMirror(
               symbol, JS('', '#[#]', JS_CURRENT_ISOLATE(), name),
-              parameterCount, isGetter, isSetter, isStatic);
-      // TODO(ahe): Cache mirrors.
-      result[symbol] = mirror;
+              parameterCount, isGetter, isSetter, isStatic, isConstructor);
+      result[i] = mirror;
       mirror._owner = this;
     }
+    return _cachedFunctionMirrors = result;
+  }
+
+  Map<Symbol, MethodMirror> get functions {
+    var result = new Map<Symbol, MethodMirror>();
+    for (JsMethodMirror mirror in _functionMirrors) {
+      if (!mirror.isConstructor) result[mirror.simpleName] = mirror;
+    }
     return result;
   }
 
@@ -213,7 +216,10 @@
     return result;
   }
 
-  List<InstanceMirror> get metadata => _metadata.map(reflect).toList();
+  List<InstanceMirror> get metadata {
+    preserveMetadata();
+    return _metadata.map(reflect).toList();
+  }
 }
 
 String n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
@@ -236,18 +242,27 @@
 final Expando<ClassMirror> classMirrors = new Expando<ClassMirror>();
 
 ClassMirror reflectType(Type key) {
-  return reflectClassByName(s('$key'.split('<')[0]));
+  return reflectClassByMangledName('$key'.split('<')[0]);
 }
 
-ClassMirror reflectClassByName(Symbol symbol) {
+ClassMirror reflectClassByMangledName(String mangledName) {
+  String unmangledName = mangledGlobalNames[mangledName];
+  if (unmangledName == null) unmangledName = mangledName;
+  return reflectClassByName(s(unmangledName), mangledName);
+}
+
+ClassMirror reflectClassByName(Symbol symbol, String mangledName) {
   disableTreeShaking();
-  String className = n(symbol);
-  var constructor = Primitives.getConstructor(className);
-  if (constructor == null) {
+  var constructorOrInterceptor =
+      Primitives.getConstructorOrInterceptor(mangledName);
+  if (constructorOrInterceptor == null) {
     // Probably an intercepted class.
     // TODO(ahe): How to handle intercepted classes?
-    throw new UnsupportedError('Cannot find class for: $className');
+    throw new UnsupportedError('Cannot find class for: ${n(symbol)}');
   }
+  var constructor = (constructorOrInterceptor is Interceptor)
+      ? JS('', '#.constructor', constructorOrInterceptor)
+      : constructorOrInterceptor;
   var descriptor = JS('', '#["@"]', constructor);
   var fields;
   var fieldsMetadata;
@@ -266,10 +281,11 @@
       fields = '';
     }
   }
-  var mirror = classMirrors[constructor];
+  var mirror = classMirrors[constructorOrInterceptor];
   if (mirror == null) {
-    mirror = new JsClassMirror(symbol, constructor, fields, fieldsMetadata);
-    classMirrors[constructor] = mirror;
+    mirror = new JsClassMirror(
+        symbol, constructorOrInterceptor, fields, fieldsMetadata);
+    classMirrors[constructorOrInterceptor] = mirror;
   }
   return mirror;
 }
@@ -322,10 +338,11 @@
                          int type,
                          String mangledName,
                          List arguments) {
+    disableTreeShaking();
     // TODO(ahe): Get the argument names.
     List<String> argumentNames = [];
-    Invocation invocation = createInvocationMirror(
-        n(name), mangledName, type, arguments, argumentNames);
+    Invocation invocation = createUnmangledInvocationMirror(
+        name, mangledName, type, arguments, argumentNames);
 
     return reflect(delegate(invocation));
   }
@@ -352,7 +369,7 @@
 
 class JsClassMirror extends JsTypeMirror with JsObjectMirror
     implements ClassMirror {
-  final _jsConstructor;
+  final _jsConstructorOrInterceptor;
   final String _fields;
   final List _fieldsMetadata;
   List _metadata;
@@ -363,7 +380,7 @@
   JsLibraryMirror _owner;
 
   JsClassMirror(Symbol simpleName,
-                this._jsConstructor,
+                this._jsConstructorOrInterceptor,
                 this._fields,
                 this._fieldsMetadata)
       : super(simpleName);
@@ -372,6 +389,30 @@
 
   Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
 
+  get _jsConstructor {
+    if (_jsConstructorOrInterceptor is Interceptor) {
+      return JS('', '#.constructor', _jsConstructorOrInterceptor);
+    } else {
+      return _jsConstructorOrInterceptor;
+    }
+  }
+
+  Map<Symbol, MethodMirror> get constructors {
+    Map<Symbol, MethodMirror> result = new Map<Symbol, MethodMirror>();
+    JsLibraryMirror library = owner;
+    String unmangledName = mangledGlobalNames[n(simpleName)];
+    if (unmangledName == null) unmangledName = n(simpleName);
+    for (JsMethodMirror mirror in library._functionMirrors) {
+      Symbol name = mirror.simpleName;
+      if (mirror.isConstructor
+          && (name == simpleName || n(name).startsWith('$unmangledName.'))) {
+        result[name] = mirror;
+        mirror._owner = this;
+      }
+    }
+    return result;
+  }
+
   List<JsMethodMirror> get _methods {
     if (_cachedMethods != null) return _cachedMethods;
     var prototype = JS('', '#.prototype', _jsConstructor);
@@ -480,15 +521,20 @@
     if (namedArguments != null && !namedArguments.isEmpty) {
       throw new UnsupportedError('Named arguments are not implemented');
     }
-    String mangledName = '${n(simpleName)}\$${n(constructorName)}';
+    String reflectiveName = 'new ${n(simpleName)}';
+    String name = n(constructorName);
+    if (!name.isEmpty) {
+      reflectiveName = '$reflectiveName\$$name';
+    }
+    reflectiveName = '$reflectiveName:${positionalArguments.length}:0';
+    String mangledName = reflectiveGlobalNames[reflectiveName];
     var factory = JS('', '#[#]', JS_CURRENT_ISOLATE(), mangledName);
     if (factory == null) {
       // TODO(ahe): Pass namedArguments when NoSuchMethodError has
       // been fixed to use Symbol.
       // TODO(ahe): What receiver to use?
       throw new NoSuchMethodError(
-          this, "constructor ${n(constructorName)}", positionalArguments,
-          null);
+          this, reflectiveName, positionalArguments, null);
     }
     return reflect(JS('', r'#.apply(#, #)',
                       factory,
@@ -510,7 +556,7 @@
 
   DeclarationMirror get owner {
     if (_owner == null) {
-      if (_jsConstructor is Interceptor) {
+      if (_jsConstructorOrInterceptor is Interceptor) {
         _owner = reflectType(Object).owner;
       } else {
         for (var list in JsMirrorSystem.librariesByName.values) {
@@ -540,8 +586,8 @@
     if (_superclass == null) {
       var superclassName = _fields.split(';')[0];
       // Use _superclass == this to represent class with no superclass (Object).
-      _superclass =
-          (superclassName == '') ? this : reflectClassByName(s(superclassName));
+      _superclass = (superclassName == '')
+          ? this : reflectClassByMangledName(superclassName);
     }
     return _superclass == this ? null : _superclass;
   }
@@ -585,6 +631,7 @@
 
   String get _prettyName => 'VariableMirror';
 
+  // TODO(ahe): Improve this information and test it.
   TypeMirror get type => JsMirrorSystem._dynamicType;
 
   DeclarationMirror get owner => _owner;
@@ -592,6 +639,7 @@
   Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
 
   List<InstanceMirror> get metadata {
+    preserveMetadata();
     if (_metadata == null) {
       _metadata = (_metadataFunction == null)
           ? const [] : JS('', '#()', _metadataFunction);
@@ -633,11 +681,12 @@
       var self = BoundClosure.selfOf(reflectee);
       return new JsMethodMirror(
           s(target), JS('', '#[#]', self, target), parameterCount,
-          false, false, isStatic);
+          false, false, isStatic, false);
     } else {
       var jsFunction = JS('', '#[#]', reflectee, callName);
       return new JsMethodMirror(
-          s(callName), jsFunction, parameterCount, false, false, isStatic);
+          s(callName), jsFunction, parameterCount,
+          false, false, isStatic, false);
     }
   }
 
@@ -662,6 +711,7 @@
   final bool isGetter;
   final bool isSetter;
   final bool isStatic;
+  final bool isConstructor;
   DeclarationMirror _owner;
   List _metadata;
 
@@ -670,7 +720,8 @@
                  this._parameterCount,
                  this.isGetter,
                  this.isSetter,
-                 this.isStatic)
+                 this.isStatic,
+                 this.isConstructor)
       : super(simpleName);
 
   factory JsMethodMirror.fromUnmangledName(String name, jsFunction) {
@@ -693,7 +744,7 @@
     }
     return new JsMethodMirror(
         s(name), jsFunction, requiredParameterCount + optionalParameterCount,
-        isGetter, isSetter, false);
+        isGetter, isSetter, false, false);
   }
 
   String get _prettyName => 'MethodMirror';
@@ -707,6 +758,9 @@
 
   Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
 
+  // TODO(ahe): Improve this information and test it.
+  TypeMirror get returnType => JsMirrorSystem._dynamicType;
+
   List<InstanceMirror> get metadata {
     if (_metadata == null) {
       _metadata = extractMetadata(_jsFunction);
@@ -723,18 +777,8 @@
 }
 
 List extractMetadata(victim) {
+  preserveMetadata();
   var metadataFunction = JS('', '#["@"]', victim);
   return (metadataFunction == null)
       ? const [] : JS('', '#()', metadataFunction);
 }
-
-List extractKeys(victim) {
-  return JS('List', '''
-(function(victim, hasOwnProperty) {
-  var result = [];
-  for (var key in victim) {
-    if (hasOwnProperty.call(victim, key)) result.push(key);
-  }
-  return result;
-})(#, Object.prototype.hasOwnProperty)''', victim);
-}
diff --git a/sdk/lib/_internal/lib/js_names.dart b/sdk/lib/_internal/lib/js_names.dart
index 5e0fc89..1d56354 100644
--- a/sdk/lib/_internal/lib/js_names.dart
+++ b/sdk/lib/_internal/lib/js_names.dart
@@ -14,7 +14,7 @@
 /// with some additional information, such as, number of required arguments.
 /// This map is for mangled names used as instance members.
 final Map<String, String> mangledNames =
-    computeMangledNames(JS('', 'init.mangledNames'));
+    computeMangledNames(JS('', 'init.mangledNames'), false);
 
 /// A map from "reflective" names to mangled names (the reverse of
 /// [mangledNames]).
@@ -24,7 +24,7 @@
 /// A map from mangled names to "reflective" names (see [mangledNames]).  This
 /// map is for globals, that is, static and top-level members.
 final Map<String, String> mangledGlobalNames =
-    computeMangledNames(JS('', 'init.mangledGlobalNames'));
+    computeMangledNames(JS('', 'init.mangledGlobalNames'), true);
 
 /// A map from "reflective" names to mangled names (the reverse of
 /// [mangledGlobalNames]).
@@ -33,12 +33,21 @@
 
 /// [jsMangledNames] is a JavaScript object literal.  The keys are the mangled
 /// names, and the values are the "reflective" names.
-Map<String, String> computeMangledNames(jsMangledNames) {
+Map<String, String> computeMangledNames(jsMangledNames, bool isGlobal) {
   preserveNames();
   var keys = extractKeys(jsMangledNames);
   var result = <String, String>{};
+  String getterPrefix = JS('String', 'init.getterPrefix');
+  int getterPrefixLength = getterPrefix.length;
+  String setterPrefix = JS('String', 'init.setterPrefix');
   for (String key in keys) {
-    result[key] = JS('String', '#[#]', jsMangledNames, key);
+    String value = JS('String', '#[#]', jsMangledNames, key);
+    result[key] = value;
+    if (!isGlobal) {
+      if (key.startsWith(getterPrefix)) {
+        result['$setterPrefix${key.substring(getterPrefixLength)}'] = '$value=';
+      }
+    }
   }
   return result;
 }
diff --git a/sdk/lib/_internal/lib/js_rti.dart b/sdk/lib/_internal/lib/js_rti.dart
index 0cd37e1..01d8ace 100644
--- a/sdk/lib/_internal/lib/js_rti.dart
+++ b/sdk/lib/_internal/lib/js_rti.dart
@@ -2,30 +2,54 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+/**
+ * This part contains helpers for supporting runtime type information.
+ *
+ * The helper use a mixture of Dart and JavaScript objects. To indicate which is
+ * used where we adopt the scheme of using explicit type annotation for Dart
+ * objects and 'var' or omitted return type for JavaScript objects.
+ *
+ * Since bool, int, and String values are represented by the same JavaScript
+ * primitives, type annotations are used for these types in all cases.
+ *
+ * Several methods use a common JavaScript encoding of runtime type information.
+ * This encoding is referred to as the type representation which is one of
+ * these:
+ *  1) a JavaScript constructor for a class C: the represented type is the raw
+ *     type C.
+ *  2) a Dart object: this is the interceptor instance for a native type.
+ *  3) a JavaScript object: this represents a class for which there is no
+ *     JavaScript constructor, because it is only used in type arguments or it
+ *     is native. The represented type is the raw type of this class.
+ *  4) a JavaScript array: the first entry is of type 1, 2 or 3 and contains the
+ *     subtyping flags and the substitution of the type and the rest of the
+ *     array are the type arguments.
+ *  5) `null`: the dynamic type.
+ *
+ *
+ * To check subtype relations between generic classes we use a JavaScript
+ * expression that describes the necessary substitution for type arguments.
+ * Such a substitution expresssion can be:
+ *  1) `null`, if no substituted check is necessary, because the
+ *     type variables are the same or there are no type variables in the class
+ *     that is checked for.
+ *  2) A list expression describing the type arguments to be used in the
+ *     subtype check, if the type arguments to be used in the check do not
+ *     depend on the type arguments of the object.
+ *  3) A function mapping the type variables of the object to be checked to
+ *     a list expression.
+ */
+
 part of _js_helper;
 
-setRuntimeTypeInfo(target, typeInfo) {
-  assert(typeInfo == null || typeInfo is JSArray);
-  // We have to check for null because factories may return null.
-  if (target != null) JS('var', r'#.$builtinTypeInfo = #', target, typeInfo);
-}
-
-getRuntimeTypeInfo(target) {
-  if (target == null) return null;
-  return JS('var', r'#.$builtinTypeInfo', target);
-}
-
-getRuntimeTypeArgument(target, substitution, index) {
-  var arguments = substitute(substitution, getRuntimeTypeInfo(target));
-  return (arguments == null) ? null : getField(arguments, index);
-}
+Type createRuntimeType(String name) => new TypeImpl(name);
 
 class TypeImpl implements Type {
   final String _typeName;
 
   TypeImpl(this._typeName);
 
-  toString() => _typeName;
+  String toString() => _typeName;
 
   // TODO(ahe): This is a poor hashCode as it collides with its name.
   int get hashCode => _typeName.hashCode;
@@ -35,21 +59,77 @@
   }
 }
 
+/**
+ * Sets the runtime type information on [target]. [typeInfo] is a type
+ * representation of type 4 or 5, that is, either a JavaScript array or
+ * [:null:].
+ */
+Object setRuntimeTypeInfo(Object target, var typeInfo) {
+  assert(isNull(typeInfo) || isJsArray(typeInfo));
+  // We have to check for null because factories may return null.
+  if (target != null) JS('var', r'#.$builtinTypeInfo = #', target, typeInfo);
+  return target;
+}
+
+/**
+ * Returns the runtime type information of [target]. The returned value is a
+ * list of type representations for the type arguments.
+ */
+getRuntimeTypeInfo(Object target) {
+  if (target == null) return null;
+  return JS('var', r'#.$builtinTypeInfo', target);
+}
+
+/**
+ * Returns the type arguments of [target] as an instance of [substitutionName].
+ */
+getRuntimeTypeArguments(target, substitutionName) {
+  var substitution =
+      getField(target, '${JS_OPERATOR_AS_PREFIX()}$substitutionName');
+  return substitute(substitution, getRuntimeTypeInfo(target));
+}
+
+/**
+ * Returns the [index]th type argument of [target] as an instance of
+ * [substitutionName].
+ */
+getRuntimeTypeArgument(Object target, String substitutionName, int index) {
+  var arguments = getRuntimeTypeArguments(target, substitutionName);
+  return isNull(arguments) ? null : getIndex(arguments, index);
+}
+
+/**
+ * Retrieves the class name from type information stored on the constructor
+ * of [object].
+ */
 String getClassName(var object) {
   return JS('String', r'#.constructor.builtin$cls', getInterceptor(object));
 }
 
-String getRuntimeTypeAsString(List runtimeType) {
-  String className = getConstructorName(runtimeType[0]);
+/**
+ * Creates the string representation for the type representation [runtimeType]
+ * of type 4, the JavaScript array, where the first element represents the class
+ * and the remaining elements represent the type arguments.
+ */
+String getRuntimeTypeAsString(var runtimeType) {
+  assert(isJsArray(runtimeType));
+  String className = getConstructorName(getIndex(runtimeType, 0));
   return '$className${joinArguments(runtimeType, 1)}';
 }
 
-String getConstructorName(type) => JS('String', r'#.builtin$cls', type);
+/**
+ * Retrieves the class name from type information stored on the constructor
+ * [type].
+ */
+String getConstructorName(var type) => JS('String', r'#.builtin$cls', type);
 
-String runtimeTypeToString(type) {
-  if (type == null) {
+/**
+ * Returns a human-readable representation of the type representation [type].
+ */
+String runtimeTypeToString(var type) {
+  if (isNull(type)) {
     return 'dynamic';
-  } else if (type is JSArray) {
+  } else if (isJsArray(type)) {
     // A list representing a type with arguments.
     return getRuntimeTypeAsString(type);
   } else {
@@ -58,18 +138,24 @@
   }
 }
 
+/**
+ * Creates a comma-separated string of human-readable representations of the
+ * type representations in the JavaScript array [types] starting at index
+ * [startIndex].
+ */
 String joinArguments(var types, int startIndex) {
-  if (types == null) return '';
+  if (isNull(types)) return '';
+  assert(isJsArray(types));
   bool firstArgument = true;
   bool allDynamic = true;
   StringBuffer buffer = new StringBuffer();
-  for (int index = startIndex; index < types.length; index++) {
+  for (int index = startIndex; index < getLength(types); index++) {
     if (firstArgument) {
       firstArgument = false;
     } else {
       buffer.write(', ');
     }
-    var argument = types[index];
+    var argument = getIndex(types, index);
     if (argument != null) {
       allDynamic = false;
     }
@@ -78,8 +164,11 @@
   return allDynamic ? '' : '<$buffer>';
 }
 
+/**
+ * Returns a human-readable representation of the type of [object].
+ */
 String getRuntimeTypeString(var object) {
-  String className = object is JSArray ? 'List' : getClassName(object);
+  String className = isJsArray(object) ? 'List' : getClassName(object);
   var typeInfo = JS('var', r'#.$builtinTypeInfo', object);
   return "$className${joinArguments(typeInfo, 0)}";
 }
@@ -89,19 +178,27 @@
   return new TypeImpl(type);
 }
 
-bool isJsFunction(var o) => JS('bool', r'typeof # == "function"', o);
-
-Object invoke(function, arguments) {
-  return JS('var', r'#.apply(null, #)', function, arguments);
-}
-
-Object call(target, name) => JS('var', r'#[#]()', target, name);
-
+/**
+ * Applies the [substitution] on the [arguments].
+ *
+ * See the comment in the beginning of this file for a description of the
+ * possible values for [substitution].
+ */
 substitute(var substitution, var arguments) {
-  if (substitution is JSArray) {
+  assert(isNull(substitution) ||
+         isJsArray(substitution) ||
+         isJsFunction(substitution));
+  assert(isNull(arguments) || isJsArray(arguments));
+  if (isJsArray(substitution)) {
     arguments = substitution;
   } else if (isJsFunction(substitution)) {
-    arguments = invoke(substitution, arguments);
+    substitution = invoke(substitution, arguments);
+    if (isJsArray(substitution)) {
+      arguments = substitution;
+    } else if (isJsFunction(substitution)) {
+      // TODO(johnniwinther): Check if this is still needed.
+      arguments = invoke(substitution, arguments);
+    }
   }
   return arguments;
 }
@@ -126,9 +223,9 @@
   // `null` or a primitive.
   // TODO(9586): Move type info for static functions onto an interceptor.
   var interceptor = getInterceptor(object);
-  bool isSubclass = getField(interceptor, isField);
+  var isSubclass = getField(interceptor, isField);
   // When we read the field and it is not there, [isSubclass] will be [:null:].
-  if (isSubclass == null || !isSubclass) return false;
+  if (isNull(isSubclass)) return false;
   // Should the asField function be passed the receiver?
   var substitution = getField(interceptor, asField);
   return checkArguments(substitution, arguments, checks);
@@ -146,7 +243,9 @@
   if (object != null && !checkSubtype(object, isField, checks, asField)) {
     String actualType = Primitives.objectTypeName(object);
     String typeName = computeTypeName(isField, checks);
-    throw new CastErrorImplementation(object, typeName);
+    // TODO(johnniwinther): Move type lookup to [CastErrorImplementation] to
+    // align with [TypeErrorImplementation].
+    throw new CastErrorImplementation(actualType, typeName);
   }
   return object;
 }
@@ -165,49 +264,136 @@
  * list [checks] (at the respective positions), possibly applying [substitution]
  * to the arguments before the check.
  *
- * See [:RuntimeTypes.getSubtypeSubstitution:] for a description of the possible
- * values for [substitution].
+ * See the comment in the beginning of this file for a description of the
+ * possible values for [substitution].
  */
 bool checkArguments(var substitution, var arguments, var checks) {
   return areSubtypes(substitute(substitution, arguments), checks);
 }
 
-bool areSubtypes(List s, List t) {
+/**
+ * Checks whether the types of [s] are all subtypes of the types of [t].
+ *
+ * [s] and [t] are either [:null:] or JavaScript arrays of type representations,
+ * A [:null:] argument is interpreted as the arguments of a raw type, that is a
+ * list of [:dynamic:]. If [s] and [t] are JavaScript arrays they must be of the
+ * same length.
+ *
+ * See the comment in the beginning of this file for a description of type
+ * representations.
+ */
+bool areSubtypes(var s, var t) {
   // [:null:] means a raw type.
-  if (s == null || t == null) return true;
+  if (isNull(s) || isNull(t)) return true;
 
-  assert(s is JSArray);
-  assert(t is JSArray);
-  assert(s.length == t.length);
+  assert(isJsArray(s));
+  assert(isJsArray(t));
+  assert(getLength(s) == getLength(t));
 
-  int len = s.length;
+  int len = getLength(s);
   for (int i = 0; i < len; i++) {
-    if (!isSubtype(s[i], t[i])) {
+    if (!isSubtype(getIndex(s, i), getIndex(t, i))) {
       return false;
     }
   }
   return true;
 }
 
-getArguments(var type) {
-  return type is JSArray ? JS('var', r'#.slice(1)', type) : null;
+Object functionSubtypeCast(Object object, String signatureName,
+                           String contextName, var context,
+                           var typeArguments) {
+  if (!checkFunctionSubtype(object, signatureName,
+                            contextName, context, typeArguments)) {
+    String actualType = Primitives.objectTypeName(object);
+    // TODO(johnniwinther): Provide better function type naming.
+    String typeName = signatureName;
+    throw new CastErrorImplementation(actualType, typeName);
+  }
+  return object;
 }
 
-getField(var object, var name) => JS('var', r'#[#]', object, name);
+Object assertFunctionSubtype(Object object, String signatureName,
+                             String contextName, var context,
+                             var typeArguments) {
+  if (!checkFunctionSubtype(object, signatureName,
+      contextName, context, typeArguments)) {
+    // TODO(johnniwinther): Provide better function type naming.
+    String typeName = signatureName;
+    throw new TypeErrorImplementation(object, typeName);
+  }
+  return object;
+}
 
-bool isSubtypeOfNull(type) {
+/**
+ * Checks that the type of [target] is a subtype of the function type denoted by
+ * [signatureName]. If the type contains type variables, [contextName] holds the
+ * name of the class where these were declared and either [context] holds the
+ * object in which the runtime values of these can be found or [typeArguments]
+ * contains these values as a list of runtime type information.
+ */
+bool checkFunctionSubtype(var target, String signatureName,
+                          String contextName, var context,
+                          var typeArguments) {
+  if (isNull(target)) return true;
+  var interceptor = getInterceptor(target);
+  if (hasField(interceptor, '${JS_OPERATOR_IS_PREFIX()}_$signatureName')) {
+    return true;
+  }
+  var signatureLocation = JS_GLOBAL_OBJECT();
+  if (isNotNull(contextName)) {
+    signatureLocation = getField(signatureLocation, contextName);
+  }
+  var typeSignature =
+      getField(signatureLocation, '${JS_SIGNATURE_NAME()}_$signatureName');
+  if (isNull(typeSignature)) {
+    // All checks can be determined statically so the type signature has not
+    // been computed.
+    return false;
+  }
+  var targetSignatureFunction = getField(interceptor, '${JS_SIGNATURE_NAME()}');
+  if (isNull(targetSignatureFunction)) return false;
+  var targetSignature = invokeOn(targetSignatureFunction, interceptor, null);
+  if (isJsFunction(typeSignature)) {
+    if (isNotNull(typeArguments)) {
+      typeSignature = invoke(typeSignature, typeArguments);
+    } else if (isNotNull(context)) {
+      typeSignature =
+          invoke(typeSignature, getRuntimeTypeArguments(context, contextName));
+    } else {
+      typeSignature = invoke(typeSignature, null);
+    }
+  }
+  return isFunctionSubtype(targetSignature, typeSignature);
+}
+
+/**
+ * Computes the signature by applying the type arguments of [context] as an
+ * instance of [contextName] to the signature function [signature].
+ */
+computeSignature(var signature, var context, var contextName) {
+  var typeArguments = getRuntimeTypeArguments(context, contextName);
+  return invokeOn(signature, context, typeArguments);
+}
+
+/**
+ * Returns [:true:] if the runtime type representation [type] is a supertype of
+ * [:Null:].
+ */
+bool isSupertypeOfNull(var type) {
   // `null` means `dynamic`.
-  return type == null || getConstructorName(type) == JS_OBJECT_CLASS_NAME();
+  return isNull(type) || getConstructorName(type) == JS_OBJECT_CLASS_NAME();
 }
 
 /**
  * Tests whether the Dart object [o] is a subtype of the runtime type
- * representation [t], which is a type representation as described in the
- * comment on [isSubtype].
+ * representation [t].
+ *
+ * See the comment in the beginning of this file for a description of type
+ * representations.
  */
 bool checkSubtypeOfRuntimeType(Object o, var t) {
-  if (JS('bool', '# == null', o)) return isSubtypeOfNull(t);
-  if (JS('bool', '# == null', t)) return true;
+  if (isNull(o)) return isSupertypeOfNull(t);
+  if (isNull(t)) return true;
   // Get the runtime type information from the object here, because we may
   // overwrite o with the interceptor below.
   var rti = getRuntimeTypeInfo(o);
@@ -216,7 +402,7 @@
   // the subtype flags and the substitution on the prototype, so they are
   // properties of the object in JS.
   var type;
-  if (JS('bool', '# != null', rti)) {
+  if (isNotNull(rti)) {
     // If the type has type variables (that is, [:rti != null:]), make a copy of
     // the type arguments and insert [o] in the first position to create a
     // compound type representation.
@@ -245,40 +431,52 @@
 }
 
 /**
- * Check whether the type represented by [s] is a subtype of the type
- * represented by [t].
+ * Extracts the type arguments from a type representation. The result is a
+ * JavaScript array or [:null:].
+ */
+getArguments(var type) {
+  return isJsArray(type) ? JS('var', r'#.slice(1)', type) : null;
+}
+
+/**
+ * Checks whether the type represented by the type representation [s] is a
+ * subtype of the type represented by the type representation [t].
  *
- * Type representations can be:
- *  1) a JavaScript constructor for a class C: the represented type is the raw
- *     type C.
- *  2) a Dart object: this is the interceptor instance for a native type.
- *  3) a JavaScript object: this represents a class for which there is no
- *     JavaScript constructor, because it is only used in type arguments or it
- *     is native. The represented type is the raw type of this class.
- *  4) a JavaScript array: the first entry is of type 1, 2 or 3 and contains the
- *     subtyping flags and the substitution of the type and the rest of the
- *     array are the type arguments.
- *  5) [:null:]: the dynamic type.
+ * See the comment in the beginning of this file for a description of type
+ * representations.
  */
 bool isSubtype(var s, var t) {
-  // If either type is dynamic, [s] is a subtype of [t].
-  if (JS('bool', '# == null', s) || JS('bool', '# == null', t)) return true;
   // Subtyping is reflexive.
-  if (JS('bool', '# === #', s, t)) return true;
-  // Get the object describing the class and check for the subtyping flag
-  // constructed from the type of [t].
-  var typeOfS = s is JSArray ? s[0] : s;
-  var typeOfT = t is JSArray ? t[0] : t;
-  // TODO(johnniwinther): replace this with the real function subtype test.
-  if (JS('bool', '#.func', s) == true || JS('bool', '#.func', t) == true ) {
+  if (isIdentical(s, t)) return true;
+  // If either type is dynamic, [s] is a subtype of [t].
+  if (isNull(s) || isNull(t)) return true;
+  if (hasField(t, '${JS_FUNCTION_TYPE_TAG()}')) {
+    if (hasNoField(s, '${JS_FUNCTION_TYPE_TAG()}')) {
+      var signatureName =
+          '${JS_OPERATOR_IS_PREFIX()}_${getField(t, JS_FUNCTION_TYPE_TAG())}';
+      if (hasField(s, signatureName)) return true;
+      var targetSignatureFunction = getField(s, '${JS_SIGNATURE_NAME()}');
+      if (isNull(targetSignatureFunction)) return false;
+      s = invokeOn(targetSignatureFunction, s, null);
+    }
+    return isFunctionSubtype(s, t);
+  }
+  // Check function types against the Function class.
+  if (getConstructorName(t) == JS_FUNCTION_CLASS_NAME() &&
+      hasField(s, '${JS_FUNCTION_TYPE_TAG()}')) {
     return true;
   }
+  // Get the object describing the class and check for the subtyping flag
+  // constructed from the type of [t].
+  var typeOfS = isJsArray(s) ? getIndex(s, 0) : s;
+  var typeOfT = isJsArray(t) ? getIndex(t, 0) : t;
   // Check for a subtyping flag.
-  var test = '${JS_OPERATOR_IS_PREFIX()}${runtimeTypeToString(typeOfT)}';
-  if (getField(typeOfS, test) == null) return false;
+  var name = runtimeTypeToString(typeOfT);
+  var test = '${JS_OPERATOR_IS_PREFIX()}${name}';
+  if (hasNoField(typeOfS, test)) return false;
   // Get the necessary substitution of the type arguments, if there is one.
   var substitution;
-  if (JS('bool', '# !== #', typeOfT, typeOfS)) {
+  if (isNotIdentical(typeOfT, typeOfS)) {
     var field = '${JS_OPERATOR_AS_PREFIX()}${runtimeTypeToString(typeOfT)}';
     substitution = getField(typeOfS, field);
   }
@@ -286,12 +484,231 @@
   // arguments and no substitution, it is used as raw type.  If [t] has no
   // type arguments, it used as a raw type.  In both cases, [s] is a subtype
   // of [t].
-  if ((s is! JSArray && JS('bool', '# == null', substitution)) ||
-      t is! JSArray) {
+  if ((!isJsArray(s) && isNull(substitution)) || !isJsArray(t)) {
     return true;
   }
   // Recursively check the type arguments.
   return checkArguments(substitution, getArguments(s), getArguments(t));
 }
 
-createRuntimeType(String name) => new TypeImpl(name);
+bool isAssignable(var s, var t) {
+  return isSubtype(s, t) || isSubtype(t, s);
+}
+
+/**
+ * If [allowShorter] is [:true:], [t] is allowed to be shorter than [s].
+ */
+bool areAssignable(List s, List t, bool allowShorter) {
+  // Both lists are empty and thus equal.
+  if (isNull(t) && isNull(s)) return true;
+  // [t] is empty (and [s] is not) => only OK if [allowShorter].
+  if (isNull(t)) return allowShorter;
+  // [s] is empty (and [t] is not) => [s] is not longer or equal to [t].
+  if (isNull(s)) return false;
+
+  assert(isJsArray(s));
+  assert(isJsArray(t));
+
+  int sLength = getLength(s);
+  int tLength = getLength(t);
+  if (allowShorter) {
+    if (sLength < tLength) return false;
+  } else {
+    if (sLength != tLength) return false;
+  }
+
+  for (int i = 0; i < tLength; i++) {
+    if (!isAssignable(getIndex(s, i), getIndex(t, i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool areAssignableMaps(var s, var t) {
+  if (isNull(t)) return true;
+  if (isNull(s)) return false;
+
+  assert(isJsObject(s));
+  assert(isJsObject(t));
+
+  return JS('bool', r'''
+     function (t, s, isAssignable) {
+       for (var $name in t) {
+         if (!s.hasOwnProperty($name)) {
+           return false;
+         }
+         var tType = t[$name];
+         var sType = s[$name];
+         if (!isAssignable.call$2(sType, tType)) {
+          return false;
+         }
+       }
+       return true;
+     }(#, #, #)
+  ''', t, s, RAW_DART_FUNCTION_REF(isAssignable));
+}
+
+bool isFunctionSubtype(var s, var t) {
+  assert(hasField(t, '${JS_FUNCTION_TYPE_TAG()}'));
+  if (hasNoField(s, '${JS_FUNCTION_TYPE_TAG()}')) return false;
+  if (hasField(s, '${JS_FUNCTION_TYPE_VOID_RETURN_TAG()}')) {
+    if (hasNoField(t, '${JS_FUNCTION_TYPE_VOID_RETURN_TAG()}') &&
+        hasField(t, '${JS_FUNCTION_TYPE_RETURN_TYPE_TAG()}')) {
+      return false;
+    }
+  } else if (hasNoField(t, '${JS_FUNCTION_TYPE_VOID_RETURN_TAG()}')) {
+    var sReturnType = getField(s, '${JS_FUNCTION_TYPE_RETURN_TYPE_TAG()}');
+    var tReturnType = getField(t, '${JS_FUNCTION_TYPE_RETURN_TYPE_TAG()}');
+    if (!isAssignable(sReturnType, tReturnType)) return false;
+  }
+  var sParameterTypes =
+      getField(s, '${JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG()}');
+  var tParameterTypes =
+      getField(t, '${JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG()}');
+
+  var sOptionalParameterTypes =
+      getField(s, '${JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG()}');
+  var tOptionalParameterTypes =
+      getField(t, '${JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG()}');
+
+  int sParametersLen =
+      isNotNull(sParameterTypes) ? getLength(sParameterTypes) : 0;
+  int tParametersLen =
+      isNotNull(tParameterTypes) ? getLength(tParameterTypes) : 0;
+
+  int sOptionalParametersLen = isNotNull(sOptionalParameterTypes)
+      ? getLength(sOptionalParameterTypes) : 0;
+  int tOptionalParametersLen = isNotNull(tOptionalParameterTypes)
+      ? getLength(tOptionalParameterTypes) : 0;
+
+  if (sParametersLen > tParametersLen) {
+    // Too many required parameters in [s].
+    return false;
+  }
+  if (sParametersLen + sOptionalParametersLen <
+      tParametersLen + tOptionalParametersLen) {
+    // Too few required and optional parameters in [s].
+    return false;
+  }
+  if (sParametersLen == tParametersLen) {
+    // Simple case: Same number of required parameters.
+    if (!areAssignable(sParameterTypes, tParameterTypes, false)) return false;
+    if (!areAssignable(sOptionalParameterTypes,
+                       tOptionalParameterTypes, true)) {
+      return false;
+    }
+  } else {
+    // Complex case: Optional parameters of [s] for required parameters of [t].
+    int pos = 0;
+    // Check all required parameters of [s].
+    for (; pos < sParametersLen; pos++) {
+      if (!isAssignable(getIndex(sParameterTypes, pos),
+                        getIndex(tParameterTypes, pos))) {
+        return false;
+      }
+    }
+    int sPos = 0;
+    int tPos = pos;
+    // Check the remaining parameters of [t] with the first optional parameters
+    // of [s].
+    for (; tPos < tParametersLen ; sPos++, tPos++) {
+      if (!isAssignable(getIndex(sOptionalParameterTypes, sPos),
+                        getIndex(tParameterTypes, tPos))) {
+        return false;
+      }
+    }
+    sPos = 0;
+    // Check the optional parameters of [t] with the remaing optional parameters
+    // of [s]:
+    for (; tPos < tOptionalParametersLen ; sPos++, tPos++) {
+      if (!isAssignable(getIndex(tOptionalParameterTypes, sPos),
+                        getIndex(tOptionalParameterTypes, tPos))) {
+        return false;
+      }
+    }
+  }
+
+  var sNamedParameters =
+      getField(s, '${JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG()}');
+  var tNamedParameters =
+      getField(t, '${JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG()}');
+  return areAssignableMaps(sNamedParameters, tNamedParameters);
+}
+
+/**
+ * Calls the JavaScript [function] with the [arguments] with the global scope
+ * as the [:this:] context.
+ */
+invoke(var function, var arguments) => invokeOn(function, null, arguments);
+
+/**
+ * Calls the JavaScript [function] with the [arguments] with [receiver] as the
+ * [:this:] context.
+ */
+Object invokeOn(function, receiver, arguments) {
+  assert(isJsFunction(function));
+  assert(isNull(arguments) || isJsArray(arguments));
+  return JS('var', r'#.apply(#, #)', function, receiver, arguments);
+}
+
+/// Calls the property [name] on the JavaScript [object].
+call(var object, String name) => JS('var', r'#[#]()', object, name);
+
+/// Returns the property [name] of the JavaScript object [object].
+getField(var object, String name) => JS('var', r'#[#]', object, name);
+
+/// Returns the property [index] of the JavaScript array [array].
+getIndex(var array, int index) {
+  assert(isJsArray(array));
+  return JS('var', r'#[#]', array, index);
+}
+
+/// Returns the length of the JavaScript array [array].
+int getLength(var array) {
+  assert(isJsArray(array));
+  return JS('int', r'#.length', array);
+}
+
+/// Returns whether [value] is a JavaScript array.
+bool isJsArray(var value) {
+  return value is JSArray;
+}
+
+hasField(var object, var name) => JS('bool', r'#[#] != null', object, name);
+
+hasNoField(var object, var name) => JS('bool', r'#[#] == null', object, name);
+
+/// Returns [:true:] if [o] is a JavaScript function.
+bool isJsFunction(var o) => JS('bool', r'typeof # == "function"', o);
+
+/// Returns [:true:] if [o] is a JavaScript object.
+bool isJsObject(var o) => JS('bool', r"typeof # == 'object'", o);
+
+/**
+ * Returns [:true:] if [o] is equal to [:null:], that is either [:null:] or
+ * [:undefined:]. We use this helper to avoid generating code under the invalid
+ * assumption that [o] is a Dart value.
+ */
+bool isNull(var o) => JS('bool', '# == null', o);
+
+/**
+ * Returns [:true:] if [o] is not equal to [:null:], that is neither [:null:]
+ * nor [:undefined:].  We use this helper to avoid generating code under the
+ * invalid assumption that [o] is a Dart value.
+ */
+bool isNotNull(var o) => JS('bool', '# != null', o);
+
+/**
+ * Returns [:true:] if the JavaScript values [s] and [t] are identical. We use
+ * this helper to avoid generating code under the invalid assumption that [s]
+ * and [t] are Dart values.
+ */
+bool isIdentical(var s, var t) => JS('bool', '# === #', s, t);
+
+/**
+ * Returns [:true:] if the JavaScript values [s] and [t] are not identical. We
+ * use this helper to avoid generating code under the invalid assumption that
+ * [s] and [t] are Dart values.
+ */
+bool isNotIdentical(var s, var t) => JS('bool', '# !== #', s, t);
diff --git a/sdk/lib/_internal/lib/js_string.dart b/sdk/lib/_internal/lib/js_string.dart
index 2da5ed4..adc32e8 100644
--- a/sdk/lib/_internal/lib/js_string.dart
+++ b/sdk/lib/_internal/lib/js_string.dart
@@ -76,24 +76,28 @@
   List<String> split(Pattern pattern) {
     checkNull(pattern);
     if (pattern is String) {
-      return JS('=List', r'#.split(#)', this, pattern);
+      return JS('JSExtendableArray', r'#.split(#)', this, pattern);
     } else if (pattern is JSSyntaxRegExp) {
       var re = regExpGetNative(pattern);
-      return JS('=List', r'#.split(#)', this, re);
+      return JS('JSExtendableArray', r'#.split(#)', this, re);
     } else {
       throw "String.split(Pattern) UNIMPLEMENTED";
     }
   }
 
-  bool startsWith(Pattern pattern) {
+  bool startsWith(Pattern pattern, [int index = 0]) {
+    if (index < 0 || index > this.length) {
+      throw new RangeError.range(index, 0, this.length);
+    }
     if (pattern is String) {
       String other = pattern;
       int otherLength = other.length;
-      if (otherLength > length) return false;
+      int endIndex = index + otherLength;
+      if (endIndex > length) return false;
       return JS('bool', r'# == #', other,
-                JS('String', r'#.substring(0, #)', this, otherLength));
+                JS('String', r'#.substring(#, #)', this, index, endIndex));
     }
-    return pattern.matchAsPrefix(this, 0) != null;
+    return pattern.matchAsPrefix(this, index) != null;
   }
 
   String substring(int startIndex, [int endIndex]) {
diff --git a/sdk/lib/_internal/lib/json_patch.dart b/sdk/lib/_internal/lib/json_patch.dart
index 01cce1a..ad22ae7 100644
--- a/sdk/lib/_internal/lib/json_patch.dart
+++ b/sdk/lib/_internal/lib/json_patch.dart
@@ -5,6 +5,7 @@
 // Patch file for dart:json library.
 
 import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show JSExtendableArray;
 
 /**
  * Parses [json] and builds the corresponding parsed JSON value.
@@ -27,7 +28,9 @@
 
   var parsed;
   try {
-    parsed = JS('=Object|=List|Null|bool|num|String', 'JSON.parse(#)', json);
+    parsed = JS('=Object|JSExtendableArray|Null|bool|num|String',
+                'JSON.parse(#)',
+                json);
   } catch (e) {
     throw new FormatException(JS('String', 'String(#)', e));
   }
@@ -54,7 +57,7 @@
     // TODO(sra): Replace this test with cheaper '#.constructor === Array' when
     // bug 621 below is fixed.
     if (JS('bool', 'Object.getPrototypeOf(#) === Array.prototype', e)) {
-      var list = JS('=List', '#', e);  // Teach compiler the type is known.
+      var list = JS('JSExtendableArray', '#', e);  // Teach compiler the type is known.
       // In-place update of the elements since JS Array is a Dart List.
       for (int i = 0; i < list.length; i++) {
         // Use JS indexing to avoid range checks.  We know this is the only
@@ -69,7 +72,7 @@
     }
 
     // Otherwise it is a plain Object, so copy to a Map.
-    var keys = JS('=List', 'Object.keys(#)', e);
+    var keys = JS('JSExtendableArray', 'Object.keys(#)', e);
     Map map = {};
     for (int i = 0; i < keys.length; i++) {
       String key = keys[i];
diff --git a/sdk/lib/_internal/lib/native_helper.dart b/sdk/lib/_internal/lib/native_helper.dart
index f4c1fe2..8ad597e 100644
--- a/sdk/lib/_internal/lib/native_helper.dart
+++ b/sdk/lib/_internal/lib/native_helper.dart
@@ -255,7 +255,7 @@
   if (interceptorsByTag == null) interceptorsByTag = JS('=Object', '{}');
   if (leafTags == null) leafTags = JS('=Object', '{}');
 
-  var tagsList = JS('=List', '#.split("|")', tags);
+  var tagsList = JS('JSExtendableArray', '#.split("|")', tags);
   for (int i = 0; i < tagsList.length; i++) {
     var tag = tagsList[i];
     JS('void', '#[#] = #', interceptorsByTag, tag, methods);
diff --git a/sdk/lib/_internal/lib/regexp_helper.dart b/sdk/lib/_internal/lib/regexp_helper.dart
index c9d9636..94b015f 100644
--- a/sdk/lib/_internal/lib/regexp_helper.dart
+++ b/sdk/lib/_internal/lib/regexp_helper.dart
@@ -84,8 +84,10 @@
   }
 
   Match firstMatch(String str) {
-    List<String> m =
-        JS('=List|Null', r'#.exec(#)', _nativeRegExp, checkString(str));
+    List<String> m = JS('JSExtendableArray|Null',
+                        r'#.exec(#)',
+                        _nativeRegExp,
+                        checkString(str));
     if (m == null) return null;
     return new _MatchImplementation(this, m);
   }
@@ -108,7 +110,7 @@
   Match _execGlobal(String string, int start) {
     Object regexp = _nativeGlobalVersion;
     JS("void", "#.lastIndex = #", regexp, start);
-    List match = JS("=List|Null", "#.exec(#)", regexp, string);
+    List match = JS("JSExtendableArray|Null", "#.exec(#)", regexp, string);
     if (match == null) return null;
     return new _MatchImplementation(this, match);
   }
@@ -116,7 +118,7 @@
   Match _execAnchored(String string, int start) {
     Object regexp = _nativeAnchoredVersion;
     JS("void", "#.lastIndex = #", regexp, start);
-    List match = JS("=List|Null", "#.exec(#)", regexp, string);
+    List match = JS("JSExtendableArray|Null", "#.exec(#)", regexp, string);
     if (match == null) return null;
     // If the last capture group participated, the original regexp did not
     // match at the start position.
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index d56bdc3..51e5037 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -152,6 +152,12 @@
       category: "Internal",
       documented: false,
       platforms: DART2JS_PLATFORM),
+
+  "_js_names": const LibraryInfo(
+      "_internal/lib/js_names.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
 };
 
 /**
diff --git a/sdk/lib/_internal/pub/lib/src/command_cache.dart b/sdk/lib/_internal/pub/lib/src/command_cache.dart
index b4131b4..9beb611 100644
--- a/sdk/lib/_internal/pub/lib/src/command_cache.dart
+++ b/sdk/lib/_internal/pub/lib/src/command_cache.dart
@@ -33,11 +33,11 @@
 
     // TODO(keertip): Add flag to list packages from non default sources
     var packagesObj = <String, Map>{};
+
     for (var package in cache.sources.defaultSource.getCachedPackages()) {
-      packagesObj[package.name] = {
-        'version': package.version.toString(),
-        'location': package.dir
-      };
+
+      var packageInfo = packagesObj.putIfAbsent(package.name, () => {});
+      packageInfo[package.version.toString()] = {'location': package.dir};
     }
 
     // TODO(keertip): Add support for non-JSON format
diff --git a/sdk/lib/_internal/pub/lib/src/dart.dart b/sdk/lib/_internal/pub/lib/src/dart.dart
index 819053c..0ad59c0 100644
--- a/sdk/lib/_internal/pub/lib/src/dart.dart
+++ b/sdk/lib/_internal/pub/lib/src/dart.dart
@@ -41,9 +41,9 @@
     }
 
     return compiler.compile(
-        pathToFileUri(entrypoint),
-        pathToFileUri(appendSlash(_libPath)),
-        pathToFileUri(appendSlash(packageRoot)),
+        path.toUri(entrypoint),
+        path.toUri(appendSlash(_libPath)),
+        path.toUri(appendSlash(packageRoot)),
         provider.readStringFromUri,
         new FormattingDiagnosticHandler(provider).diagnosticHandler,
         options);
diff --git a/sdk/lib/_internal/pub/lib/src/io.dart b/sdk/lib/_internal/pub/lib/src/io.dart
index 8b6c7fd..66477f5 100644
--- a/sdk/lib/_internal/pub/lib/src/io.dart
+++ b/sdk/lib/_internal/pub/lib/src/io.dart
@@ -368,7 +368,7 @@
 
 /// Whether pub is running from within the Dart SDK, as opposed to from the Dart
 /// source repository.
-bool get runningFromSdk => path.extension(new Options().script) == '.snapshot';
+bool get runningFromSdk => path.extension(Platform.script) == '.snapshot';
 
 /// Resolves [target] relative to the path to pub's `resource` directory.
 String resourcePath(String target) {
@@ -591,19 +591,12 @@
     executable = "cmd";
   }
 
-  var env = null;
-  if (environment != null) {
-    env = new Map.from(Platform.environment);
-    environment.forEach((key, value) => env[key] = value);
-  }
-
-
   log.process(executable, args);
 
   return fn(executable,
             args,
             workingDirectory: workingDir,
-            environment: env);
+            environment: environment);
 }
 
 /// Wraps [input] to provide a timeout. If [input] completes before
@@ -772,7 +765,7 @@
     // Create the tar file.
     var tarFile = path.join(tempDir, "intermediate.tar");
     var args = ["a", "-w$baseDir", tarFile];
-    args.addAll(contents.map((entry) => '-i!"$entry"'));
+    args.addAll(contents.map((entry) => '-i!$entry'));
 
     // We're passing 'baseDir' both as '-w' and setting it as the working
     // directory explicitly here intentionally. The former ensures that the
diff --git a/sdk/lib/_internal/pub/lib/src/sdk.dart b/sdk/lib/_internal/pub/lib/src/sdk.dart
index 0fbe5f9..7f4e26a 100644
--- a/sdk/lib/_internal/pub/lib/src/sdk.dart
+++ b/sdk/lib/_internal/pub/lib/src/sdk.dart
@@ -29,7 +29,7 @@
   }
 
   // Assume the Dart executable is always coming from the SDK.
-  return path.dirname(path.dirname(new Options().executable));
+  return path.dirname(path.dirname(Platform.executable));
 }
 
 /// Gets the SDK's revision number formatted to be a semantic version.
diff --git a/sdk/lib/_internal/pub/lib/src/utils.dart b/sdk/lib/_internal/pub/lib/src/utils.dart
index c67ce57..d5210f3 100644
--- a/sdk/lib/_internal/pub/lib/src/utils.dart
+++ b/sdk/lib/_internal/pub/lib/src/utils.dart
@@ -376,37 +376,7 @@
 /// be globally unique, or the wrong library path may be returned.
 String libraryPath(String libraryName) {
   var libraries = currentMirrorSystem().findLibrary(new Symbol(libraryName));
-  return fileUriToPath(libraries.single.uri);
-}
-
-/// Converts a `file:` [Uri] to a local path string.
-String fileUriToPath(Uri uri) {
-  if (uri.scheme != 'file') {
-    throw new ArgumentError("Uri $uri must have scheme 'file:'.");
-  }
-  if (Platform.operatingSystem != 'windows') return uri.path;
-  if (uri.path.startsWith("/")) {
-    // Drive-letter paths look like "file:///C:/path/to/file". The replaceFirst
-    // removes the extra initial slash.
-    return uri.path.replaceFirst("/", "").replaceAll("/", "\\");
-  } else {
-    // Network paths look like "file://hostname/path/to/file".
-    return "\\\\${uri.path.replaceAll("/", "\\")}";
-  }
-}
-
-/// Converts a local path string to a `file:` [Uri].
-Uri pathToFileUri(String pathString) {
-  pathString = path.absolute(pathString);
-  if (Platform.operatingSystem != 'windows') {
-    return Uri.parse('file://$pathString');
-  } else if (path.rootPrefix(pathString).startsWith('\\\\')) {
-    // Network paths become "file://hostname/path/to/file".
-    return Uri.parse('file:${pathString.replaceAll("\\", "/")}');
-  } else {
-    // Drive-letter paths become "file:///C:/path/to/file".
-    return Uri.parse('file:///${pathString.replaceAll("\\", "/")}');
-  }
+  return path.fromUri(libraries.single.uri);
 }
 
 /// Gets a "special" string (ANSI escape or Unicode). On Windows, returns
diff --git a/sdk/lib/_internal/pub/test/pub_cache_test.dart b/sdk/lib/_internal/pub/test/pub_cache_test.dart
index 195bcd5..f902a92 100644
--- a/sdk/lib/_internal/pub/test/pub_cache_test.dart
+++ b/sdk/lib/_internal/pub/test/pub_cache_test.dart
@@ -73,9 +73,9 @@
     ]).create();
 
     schedulePub(args: ['cache', 'list'], output:
-      new RegExp(r'\{"packages":\{"bar":\{"version":"2\.0\.0","location":'
-          r'"[^"]+bar-2\.0\.0"\},"foo":\{"version":"1\.2\.3","location":'
-          r'"[^"]+foo-1\.2\.3"\}\}\}$'));
+      new RegExp(r'\{"packages":\{"bar":\{"2\.0\.0":\{"location":'
+          r'"[^"]+bar-2\.0\.0"\}},"foo":\{"1\.2\.3":\{"location":'
+          r'"[^"]+foo-1\.2\.3"\}\}\}\}$'));
   });
 
   integration('includes packages containing deps with bad sources', () {
@@ -92,7 +92,7 @@
     ]).create();
 
     schedulePub(args: ['cache', 'list'], output:
-      new RegExp(r'\{"packages":\{"foo":\{"version":"1\.2\.3","location":'
-          r'"[^"]+foo-1\.2\.3"\}\}\}$'));
+      new RegExp(r'\{"packages":\{"foo":\{"1\.2\.3":\{"location":'
+          r'"[^"]+foo-1\.2\.3"\}\}\}\}$'));
   });
 }
\ No newline at end of file
diff --git a/sdk/lib/_internal/pub/test/test_pub.dart b/sdk/lib/_internal/pub/test/test_pub.dart
index 4813ee4..c35ab69 100644
--- a/sdk/lib/_internal/pub/test/test_pub.dart
+++ b/sdk/lib/_internal/pub/test/test_pub.dart
@@ -436,7 +436,7 @@
 
   // 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;
+  var dartBin = Platform.executable;
 
   // If the executable looks like a path, get its full path. That way we
   // can still find it when we spawn it with a different working directory.
@@ -453,8 +453,7 @@
 
   if (tokenEndpoint == null) tokenEndpoint = new Future.value();
   var environmentFuture = tokenEndpoint.then((tokenEndpoint) {
-    // TODO(nweiz): remove this when issue 9294 is fixed.
-    var environment = new Map.from(Platform.environment);
+    var environment = {};
     environment['_PUB_TESTING'] = 'true';
     environment['PUB_CACHE'] = pathInSandbox(cachePath);
     environment['DART_SDK'] = pathInSandbox(sdkPath);
@@ -556,7 +555,7 @@
 /// The path to the `packages` directory from which pub loads its dependencies.
 String get _packageRoot {
   return path.absolute(path.join(
-      path.dirname(new Options().executable), '..', '..', 'packages'));
+      path.dirname(Platform.executable), '..', '..', 'packages'));
 }
 
 /// Skips the current test if Git is not installed. This validates that the
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index bff0435..0de2919 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -76,6 +76,11 @@
 
   /**
    * Creates a single-subscription stream that gets its data from [data].
+   *
+   * If iterating [data] throws an error, the stream ends immediately with
+   * that error. No done event will be sent (iteration is not complete), but no
+   * further data events will be generated either, since iteration cannot
+   * continue.
    */
   factory Stream.fromIterable(Iterable<T> data) {
     return new _GeneratedStreamImpl<T>(
@@ -307,12 +312,12 @@
   }
 
   /**
-   * Checks whether [match] occurs in the elements provided by this stream.
+   * Checks whether [needle] occurs in the elements provided by this stream.
    *
    * Completes the [Future] when the answer is known.
    * If this stream reports an error, the [Future] will report that error.
    */
-  Future<bool> contains(T match) {
+  Future<bool> contains(Object needle) {
     _FutureImpl<bool> future = new _FutureImpl<bool>();
     StreamSubscription subscription;
     subscription = this.listen(
@@ -320,7 +325,7 @@
         // checked mode. http://dartbug.com/7733
         (/*T*/ element) {
           _runUserCode(
-            () => (element == match),
+            () => (element == needle),
             (bool isMatch) {
               if (isMatch) {
                 subscription.cancel();
@@ -673,8 +678,8 @@
    * with no [defaultValue] function provided, the future will receive an
    * error.
    */
-  Future<T> firstWhere(bool test(T element), {T defaultValue()}) {
-    _FutureImpl<T> future = new _FutureImpl<T>();
+  Future<dynamic> firstWhere(bool test(T element), {Object defaultValue()}) {
+    _FutureImpl<dynamic> future = new _FutureImpl();
     StreamSubscription subscription;
     subscription = this.listen(
       // TODO(ahe): Restore type when feature is implemented in dart2js
@@ -710,8 +715,8 @@
    * That means that the result cannot be provided before this stream
    * is done.
    */
-  Future<T> lastWhere(bool test(T element), {T defaultValue()}) {
-    _FutureImpl<T> future = new _FutureImpl<T>();
+  Future<dynamic> lastWhere(bool test(T element), {Object defaultValue()}) {
+    _FutureImpl<dynamic> future = new _FutureImpl();
     T result = null;
     bool foundResult = false;
     StreamSubscription subscription;
diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart
index e5aca17..9438452 100644
--- a/sdk/lib/async/stream_pipe.dart
+++ b/sdk/lib/async/stream_pipe.dart
@@ -151,8 +151,6 @@
   }
 
   void _handleDone() {
-    // On a done-event, we have already been unsubscribed.
-    _subscription = null;
     _stream._handleDone(this);
   }
 }
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index b92aa16..1379128 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -410,10 +410,10 @@
 
   _ZoneTimer(this._zone, Duration duration, this._callback) {
     _zone.expectCallback();
-    _timer = _createTimer(duration, this.run);
+    _timer = _createTimer(duration, this._run);
   }
 
-  void run() {
+  void _run() {
     _isDone = true;
     _zone.executeCallbackGuarded(_callback);
   }
@@ -438,10 +438,10 @@
 
   _PeriodicZoneTimer(this._zone, Duration duration, this._callback) {
     _zone.expectCallback();
-    _timer = _createPeriodicTimer(duration, this.run);
+    _timer = _createPeriodicTimer(duration, this._run);
   }
 
-  void run(Timer timer) {
+  void _run(Timer timer) {
     assert(identical(_timer, timer));
     _zone.executePeriodicCallbackGuarded(() { _callback(this); });
   }
diff --git a/sdk/lib/collection/hash_map.dart b/sdk/lib/collection/hash_map.dart
index 2aea9c9..ab1f09c 100644
--- a/sdk/lib/collection/hash_map.dart
+++ b/sdk/lib/collection/hash_map.dart
@@ -29,17 +29,17 @@
   external Iterable<K> get keys;
   external Iterable<V> get values;
 
-  external bool containsKey(K key);
-  external bool containsValue(V value);
+  external bool containsKey(Object key);
+  external bool containsValue(Object value);
 
   external void addAll(Map<K, V> other);
 
-  external V operator [](K key);
+  external V operator [](Object key);
   external void operator []=(K key, V value);
 
   external V putIfAbsent(K key, V ifAbsent());
 
-  external V remove(K key);
+  external V remove(Object key);
   external void clear();
 
   external void forEach(void action(K key, V value));
diff --git a/sdk/lib/collection/hash_set.dart b/sdk/lib/collection/hash_set.dart
index e2c797d..86c69c8 100644
--- a/sdk/lib/collection/hash_set.dart
+++ b/sdk/lib/collection/hash_set.dart
@@ -7,8 +7,8 @@
 /** Common parts of [HashSet] and [LinkedHashSet] implementations. */
 abstract class _HashSetBase<E> extends IterableBase<E> implements Set<E> {
   // Set.
-  bool containsAll(Iterable<E> other) {
-    for (E object in other) {
+  bool containsAll(Iterable<Object> other) {
+    for (Object object in other) {
       if (!this.contains(object)) return false;
     }
     return true;
@@ -17,10 +17,10 @@
   /** Create a new Set of the same type as this. */
   Set _newSet();
 
-  Set<E> intersection(Set<E> other) {
+  Set<E> intersection(Set<Object> other) {
     Set<E> result = _newSet();
     if (other.length < this.length) {
-      for (E element in other) {
+      for (var element in other) {
         if (this.contains(element)) result.add(element);
       }
     } else {
@@ -95,7 +95,7 @@
 
   external bool remove(Object object);
 
-  external void removeAll(Iterable objectsToRemove);
+  external void removeAll(Iterable<Object> objectsToRemove);
 
   external void removeWhere(bool test(E element));
 
diff --git a/sdk/lib/collection/iterable.dart b/sdk/lib/collection/iterable.dart
index a950543..6dbf92d 100644
--- a/sdk/lib/collection/iterable.dart
+++ b/sdk/lib/collection/iterable.dart
@@ -17,7 +17,7 @@
   Iterable expand(Iterable f(E element)) =>
       new ExpandIterable<E, dynamic>(this, f);
 
-  bool contains(E element) {
+  bool contains(Object element) {
     for (E e in this) {
       if (e == element) return true;
     }
@@ -141,8 +141,7 @@
     return result;
   }
 
-  E firstWhere(bool test(E value), { E orElse() }) {
-    // TODO(floitsch): check that arguments are of correct type?
+  dynamic firstWhere(bool test(E value), { Object orElse() }) {
     for (E element in this) {
       if (test(element)) return element;
     }
@@ -150,8 +149,7 @@
     throw new StateError("No matching element");
   }
 
-  E lastWhere(bool test(E value), {E orElse()}) {
-    // TODO(floitsch): check that arguments are of correct type?
+  dynamic lastWhere(bool test(E value), { Object orElse() }) {
     E result = null;
     bool foundMatching = false;
     for (E element in this) {
@@ -166,7 +164,6 @@
   }
 
   E singleWhere(bool test(E value)) {
-    // TODO(floitsch): check that argument is of correct type?
     E result = null;
     bool foundMatching = false;
     for (E element in this) {
@@ -211,7 +208,7 @@
   Iterable expand(Iterable f(E element)) =>
       new ExpandIterable<E, dynamic>(this, f);
 
-  bool contains(E element) {
+  bool contains(Object element) {
     for (E e in this) {
       if (e == element) return true;
     }
@@ -335,8 +332,7 @@
     return result;
   }
 
-  E firstWhere(bool test(E value), { E orElse() }) {
-    // TODO(floitsch): check that arguments are of correct type?
+  dynamic firstWhere(bool test(E value), { Object orElse() }) {
     for (E element in this) {
       if (test(element)) return element;
     }
@@ -344,8 +340,7 @@
     throw new StateError("No matching element");
   }
 
-  E lastWhere(bool test(E value), {E orElse()}) {
-    // TODO(floitsch): check that arguments are of correct type?
+  dynamic lastWhere(bool test(E value), { Object orElse() }) {
     E result = null;
     bool foundMatching = false;
     for (E element in this) {
@@ -360,7 +355,6 @@
   }
 
   E singleWhere(bool test(E value)) {
-    // TODO(floitsch): check that argument is of correct type?
     E result = null;
     bool foundMatching = false;
     for (E element in this) {
diff --git a/sdk/lib/collection/linked_hash_map.dart b/sdk/lib/collection/linked_hash_map.dart
index 8e6538c..3082ce0 100644
--- a/sdk/lib/collection/linked_hash_map.dart
+++ b/sdk/lib/collection/linked_hash_map.dart
@@ -25,19 +25,19 @@
     return new LinkedHashMap<K, V>()..addAll(other);
   }
 
-  external bool containsKey(K key);
+  external bool containsKey(Object key);
 
-  external bool containsValue(V value);
+  external bool containsValue(Object value);
 
   external void addAll(Map<K, V> other);
 
-  external V operator [](K key);
+  external V operator [](Object key);
 
   external void operator []=(K key, V value);
 
   external V putIfAbsent(K key, V ifAbsent());
 
-  external V remove(K key);
+  external V remove(Object key);
 
   external void clear();
 
diff --git a/sdk/lib/collection/list.dart b/sdk/lib/collection/list.dart
index fa1bd50..5c81ae7 100644
--- a/sdk/lib/collection/list.dart
+++ b/sdk/lib/collection/list.dart
@@ -63,7 +63,7 @@
     return this[0];
   }
 
-  bool contains(E element) {
+  bool contains(Object element) {
     int length = this.length;
     for (int i = 0; i < length; i++) {
       if (this[i] == element) return true;
@@ -96,7 +96,7 @@
     return false;
   }
 
-  E firstWhere(bool test(E element), { E orElse() }) {
+  dynamic firstWhere(bool test(E element), { Object orElse() }) {
     int length = this.length;
     for (int i = 0; i < length; i++) {
       E element = this[i];
@@ -109,7 +109,7 @@
     throw new StateError("No matching element");
   }
 
-  E lastWhere(bool test(E element), { E orElse() }) {
+  dynamic lastWhere(bool test(E element), { Object orElse() }) {
     int length = this.length;
     for (int i = length - 1; i >= 0; i--) {
       E element = this[i];
@@ -385,7 +385,7 @@
     insertAll(start, newContents);
   }
 
-  int indexOf(E element, [int startIndex = 0]) {
+  int indexOf(Object element, [int startIndex = 0]) {
     if (startIndex >= this.length) {
       return -1;
     }
@@ -405,7 +405,7 @@
    * the search at index [startIndex] to 0.
    * Returns -1 if [element] is not found.
    */
-  int lastIndexOf(E element, [int startIndex]) {
+  int lastIndexOf(Object element, [int startIndex]) {
     if (startIndex == null) {
       startIndex = this.length - 1;
     } else {
diff --git a/sdk/lib/collection/splay_tree.dart b/sdk/lib/collection/splay_tree.dart
index 20cc84c..84e61e1 100644
--- a/sdk/lib/collection/splay_tree.dart
+++ b/sdk/lib/collection/splay_tree.dart
@@ -255,8 +255,9 @@
 
   SplayTreeMap._internal();
 
-  V operator [](K key) {
+  V operator [](Object key) {
     if (key == null) throw new ArgumentError(key);
+    if (key is! K) return null;
     if (_root != null) {
       int comp = _splay(key);
       if (comp == 0) {
@@ -337,11 +338,11 @@
     _clear();
   }
 
-  bool containsKey(K key) {
-    return _splay(key) == 0;
+  bool containsKey(Object key) {
+    return key is K && _splay(key) == 0;
   }
 
-  bool containsValue(V value) {
+  bool containsValue(Object value) {
     bool found = false;
     int initialSplayCount = _splayCount;
     bool visit(_SplayTreeMapNode node) {
diff --git a/sdk/lib/core/double.dart b/sdk/lib/core/double.dart
index d07e9c2..0028f91 100644
--- a/sdk/lib/core/double.dart
+++ b/sdk/lib/core/double.dart
@@ -149,6 +149,9 @@
    * used instead. If no handleError is provided, a [FormatException]
    * is thrown.
    *
+   * The [onError] function is only invoked if [source] is a [String]. It is
+   * not invoked if the [source] is, for example, `null`.
+   *
    * Examples of accepted strings:
    *
    *     "3.14"
diff --git a/sdk/lib/core/duration.dart b/sdk/lib/core/duration.dart
index a0cf1b6..a19c651 100644
--- a/sdk/lib/core/duration.dart
+++ b/sdk/lib/core/duration.dart
@@ -82,9 +82,12 @@
   /**
    * Multiplies this [Duration] by the given [factor] and returns the result
    * as a new [Duration].
+   *
+   * Note that when [factor] is a double, and the duration is greater than
+   * 53 bits, precision is lost because of double-precision arithmetic.
    */
-  Duration operator *(int factor) {
-    return new Duration(microseconds: _duration * factor);
+  Duration operator *(num factor) {
+    return new Duration(microseconds: (_duration * factor).round());
   }
 
   /**
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index 245fc49..060eba7 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -235,13 +235,6 @@
   String toString() => "Stack Overflow";
 }
 
-class FiftyThreeBitOverflowError implements Error {
-  final Object value;
-
-  const FiftyThreeBitOverflowError(this.value);
-  String toString() => "53-bit Overflow: $value";
-}
-
 /**
  * Error thrown when a lazily initialized variable cannot be initialized.
  *
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 4518b7b..2dd2be2 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -111,6 +111,9 @@
    * sign, the [onError] is called with the [source] as argument, and its return
    * value is used instead. If no [onError] is provided, a [FormatException]
    * is thrown.
+   *
+   * The [onError] function is only invoked if [source] is a [String]. It is
+   * not invoked if the [source] is, for example, `null`.
    */
   external static int parse(String source,
                             { int radix,
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 41972b9..9d919ae 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -76,7 +76,7 @@
   /**
    * Check whether the collection contains an element equal to [element].
    */
-  bool contains(E element);
+  bool contains(Object element);
 
   /**
    * Applies the function [f] to each element of this collection.
@@ -171,6 +171,8 @@
    *
    * The returned [Iterable] may contain fewer than [n] elements, if `this`
    * contains fewer than [n] elements.
+   *
+   * It is an error if [n] is negative.
    */
   Iterable<E> take(int n);
 
@@ -191,6 +193,8 @@
    *
    * If `this` has fewer than [n] elements, then the resulting [Iterable] will
    * be empty.
+   *
+   * It is an error if [n] is negative.
    */
   Iterable<E> skip(int n);
 
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 419527e..7bb8b5d 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -295,7 +295,7 @@
   List<E> sublist(int start, [int end]);
 
   /**
-   * Returns an [Iterable] that iterators over the elements in the range
+   * Returns an [Iterable] that iterates over the elements in the range
    * [start] to [end] exclusive. The result of this function
    * is backed by `this`.
    *
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index 4f67ea1..88776c1 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.dart
@@ -22,12 +22,12 @@
   /**
    * Returns whether this map contains the given [value].
    */
-  bool containsValue(V value);
+  bool containsValue(Object value);
 
   /**
    * Returns whether this map contains the given [key].
    */
-  bool containsKey(K key);
+  bool containsKey(Object key);
 
   /**
    * Returns the value for the given [key] or null if [key] is not
@@ -35,7 +35,7 @@
    * use containsKey to distinguish between an absent key and a null
    * value, or use the [putIfAbsent] method.
    */
-  V operator [](K key);
+  V operator [](Object key);
 
   /**
    * Associates the [key] with the given [value].
@@ -69,7 +69,7 @@
    * can be null and a returned null value does not always imply that the
    * key is absent.
    */
-  V remove(K key);
+  V remove(Object key);
 
   /**
    * Removes all pairs from the map.
@@ -86,7 +86,6 @@
   /**
    * The keys of [this].
    */
-  // TODO(floitsch): this should return a [Set].
   Iterable<K> get keys;
 
   /**
diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart
index 19dbbe2..b9b3616 100644
--- a/sdk/lib/core/num.dart
+++ b/sdk/lib/core/num.dart
@@ -165,7 +165,7 @@
   double toDouble();
 
   /**
-   * Converts [this] to a [double] and then gives string representation with
+   * Converts `this` to a [double] and returns its string representation with
    * [fractionDigits] digits after the decimal point.
    *
    * The parameter [fractionDigits] must be an integer satisfying:
@@ -174,8 +174,9 @@
   String toStringAsFixed(int fractionDigits);
 
   /**
-   * Converts [this] to a [double] and then gives a string in decimal
-   * exponential notation with [fractionDigits] digits after the decimal point.
+   * Converts `this` to a [double] and returns its string representation in
+   * decimal exponential notation with [fractionDigits] digits after the decimal
+   * point.
    *
    * If [fractionDigits] is given then it must be an integer satisfying:
    * [:0 <= fractionDigits <= 20:]. Without the parameter the returned string
@@ -184,11 +185,49 @@
   String toStringAsExponential([int fractionDigits]);
 
   /**
-   * Converts [this] to a double and gives a string representation with
+   * Converts `this` to a double and returns its string representation with
    * [precision] significant digits.
    *
    * The parameter [precision] must be an integer satisfying:
    * [:1 <= precision <= 21:].
    */
   String toStringAsPrecision(int precision);
+
+  /**
+   * Computes the shortest string of digits that correctly represent the input
+   * number.
+   *
+   * [double]s in the range `10^-6` (inclusive) to `10^21` (exclusive)
+   * are converted to their decimal representation with at least one digit
+   * after the decimal point. For all other doubles,
+   * except for special values like `NaN` or `Infinity`, this method returns an
+   * exponential representation (see [toStringAsExponential]).
+   *
+   * Returns `"NaN"` for [double.NAN], `"Infinity"` for [double.INFINITY], and
+   * `"-Infinity"` for [double.MINUS_INFINITY].
+   *
+   * [int]s are always converted to their decimal representation.
+   *
+   * Examples:
+   *
+   *     (0.000001).toString(); // "0.000001"
+   *     (0.0000001).toString(); // "1e-7"
+   *     (111111111111111111111.0).toString(); // "111111111111111110000.0"
+   *     (100000000000000000000.0).toString(); // "100000000000000000000.0"
+   *     (1000000000000000000000.0).toString(); // "1e+21"
+   *     (1111111111111111111111.0).toString(); // "1.1111111111111111e+21"
+   *     1.toString(); // "1"
+   *     111111111111111111111.toString(); // "111111111111111110000"
+   *     100000000000000000000.toString(); // "100000000000000000000"
+   *     1000000000000000000000.toString(); // "1000000000000000000000"
+   *     1111111111111111111111.toString(); // "1111111111111111111111"
+   *
+   * Note: the conversion may round the output if the returned string
+   * is accurate enough to uniquely identify the input-number.
+   * For example the most precise representation of the [double] `9e59` equals
+   * `"899999999999999918767229449717619953810131273674690656206848"`, but
+   * this method returns the shorter (but still correct) `"9e59"`.
+   *
+   */
+  String toString();
 }
diff --git a/sdk/lib/core/set.dart b/sdk/lib/core/set.dart
index 7b5980e..aaab5ec 100644
--- a/sdk/lib/core/set.dart
+++ b/sdk/lib/core/set.dart
@@ -42,7 +42,7 @@
   /**
    * Returns true if [value] is in the set.
    */
-  bool contains(E value);
+  bool contains(Object value);
 
   /**
    * Adds [value] into the set.
@@ -69,12 +69,12 @@
   /**
    * Removes each element of [elements] from this set.
    */
-  void removeAll(Iterable elements);
+  void removeAll(Iterable<Object> elements);
 
   /**
    * Removes all elements of this set that are not elements in [elements].
    */
-  void retainAll(Iterable elements);
+  void retainAll(Iterable<Object> elements);
 
   /**
    * Removes all elements of this set that satisfy [test].
@@ -89,7 +89,7 @@
   /**
    * Returns whether this Set contains all the elements of [other].
    */
-  bool containsAll(Iterable<E> other);
+  bool containsAll(Iterable<Object> other);
 
   /**
    * Returns a new set which is the intersection between this set and [other].
@@ -97,7 +97,7 @@
    * That is, the returned set contains all the elements of this `Set` that
    * are also elements of [other].
    */
-  Set<E> intersection(Set<E> other);
+  Set<E> intersection(Set<Object> other);
 
   /**
    * Returns a new set which contains all the elements of this set and [other].
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 0d2503a..e2ffc23 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -106,8 +106,18 @@
 
   /**
    * Returns whether this string starts with a match of [pattern].
+   *
+   * If [index] is provided, instead check if the substring starting
+   * at that index starts with a match of [pattern].
+   *
+   * It is an error if [index] is negative or greater than [length].
+   *
+   * A [RegExp] containing "^" will not match if the [index] is greater than
+   * zero. The pattern works on the string as a whole, and does not extract
+   * a substring starting at [index] first. That is.
+   *     "abc".startsWith(new RegExp("^.", 1)) == false
    */
-  bool startsWith(Pattern pattern);
+  bool startsWith(Pattern pattern, [int index = 0]);
 
   /**
    * Returns the first position of a match of [pattern] in this string,
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index c0a7fdf..0eaee85 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -108,7 +108,7 @@
          fragment: _emptyIfNull(m[_COMPONENT_FRAGMENT]));
 
   /**
-   * Create a new URI from its components.
+   * Creates a new URI from its components.
    *
    * Each component is set through a named argument. Any number of
    * components can be provided. The default value for the components
@@ -178,6 +178,91 @@
   }
 
   /**
+   * Creates a new `http` URI from authority, path and query.
+   *
+   * Examples:
+   *
+   *     // Create the URI http://example.org/path?q=abc.
+   *     new Uri.http("google.com", "/search", { "q" : "dart" });http://example.org/path?q=abc.
+   *     new Uri.http("user:pass@localhost:8080, "");  // http://user:pass@localhost:8080/
+   *     new Uri.http("example.org, "a b");  // http://example.org/a%20b
+   *     new Uri.http("example.org, "/a%2F");  // http://example.org/a%25%2F
+   *
+   * The `scheme` is always set to `http`.
+   *
+   * The `userInfo`, `host` and `port` components are set from the
+   * [authority] argument.
+   *
+   * The `path` component is set from the [unencodedPath]
+   * argument. The path passed must not be encoded as this constructor
+   * encodes the path.
+   *
+   * The `query` component is set from the optional [queryParameters]
+   * argument.
+   */
+  factory Uri.http(String authority,
+                   String unencodedPath,
+                   [Map<String, String> queryParameters]) {
+    return _makeHttpUri("http", authority, unencodedPath, queryParameters);
+  }
+
+  /**
+   * Creates a new `https` URI from authority, path and query.
+   *
+   * This constructor is the same as [Uri.http] except for the scheme
+   * which is set to `https`.
+   */
+  factory Uri.https(String authority,
+                    String unencodedPath,
+                    [Map<String, String> queryParameters]) {
+    return _makeHttpUri("https", authority, unencodedPath, queryParameters);
+  }
+
+  static Uri _makeHttpUri(String scheme,
+                          String authority,
+                          String unencodedPath,
+                          Map<String, String> queryParameters) {
+    var userInfo = "";
+    var host = "";
+    var port = 0;
+
+    var hostStart = 0;
+    // Split off the user info.
+    bool hasUserInfo = false;
+    for (int i = 0; i < authority.length; i++) {
+      if (authority.codeUnitAt(i) == _AT_SIGN) {
+        hasUserInfo = true;
+        userInfo = authority.substring(0, i);
+        hostStart = i + 1;
+        break;
+      }
+    }
+    // Split host and port.
+    bool hasPort = false;
+    for (int i = hostStart; i < authority.length; i++) {
+      if (authority.codeUnitAt(i) == _COLON) {
+        hasPort = true;
+        host = authority.substring(hostStart, i);
+        if (!host.isEmpty) {
+          var portString = authority.substring(i + 1);
+          if (portString.isNotEmpty) port = int.parse(portString);
+        }
+        break;
+      }
+    }
+    if (!hasPort) {
+      host = hasUserInfo ? authority.substring(hostStart) : authority;
+    }
+
+    return new Uri(scheme: scheme,
+                   userInfo: userInfo,
+                   host: host,
+                   port: port,
+                   pathSegments: unencodedPath.split("/"),
+                   queryParameters: queryParameters);
+  }
+
+  /**
    * Returns the URI path split into its segments. Each of the
    * segments in the returned list have been decoded. If the path is
    * empty the empty list will be returned. A leading slash `/` does
@@ -746,6 +831,7 @@
   static const int _ZERO = 0x30;
   static const int _NINE = 0x39;
   static const int _COLON = 0x3A;
+  static const int _AT_SIGN = 0x40;
   static const int _UPPER_CASE_A = 0x41;
   static const int _UPPER_CASE_F = 0x46;
   static const int _LOWER_CASE_A = 0x61;
@@ -1016,9 +1102,9 @@
   final Map _map;
   const _UnmodifiableMap(this._map);
 
-  bool containsValue(V value) => _map.containsValue(value);
-  bool containsKey(K key) => _map.containsKey(key);
-  V operator [](K key) => _map[key];
+  bool containsValue(Object value) => _map.containsValue(value);
+  bool containsKey(Object key) => _map.containsKey(key);
+  V operator [](Object key) => _map[key];
   void operator []=(K key, V value) {
     throw new UnsupportedError("Cannot modify an unmodifiable map");
   }
@@ -1028,7 +1114,7 @@
   addAll(Map other) {
     throw new UnsupportedError("Cannot modify an unmodifiable map");
   }
-  V remove(K key) {
+  V remove(Object key) {
     throw new UnsupportedError("Cannot modify an unmodifiable map");
   }
   void clear() {
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index abafc22..8f155b4 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -1,4 +1,8 @@
 /// The Dart HTML library.
+///
+/// For examples, see
+/// [Dart HTML5 Samples](https://github.com/dart-lang/dart-html5-samples)
+/// on Github.
 library dart.dom.html;
 
 import 'dart:async';
@@ -16,7 +20,7 @@
 import 'dart:web_gl' as gl;
 import 'dart:web_sql';
 import 'dart:_js_helper' show convertDartClosureToJS, Creates, JavaScriptIndexingBehavior, JSName, Null, Returns;
-import 'dart:_interceptors' show Interceptor;
+import 'dart:_interceptors' show Interceptor, JSExtendableArray;
 import 'dart:_isolate_helper' show IsolateNatives;
 import 'dart:_foreign_helper' show JS;
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -855,7 +859,7 @@
    *     var ctx = canvas.context2D
    *     ..fillStyle = "rgb(200,0,0)"
    *     ..fillRect(10, 10, 55, 50);
-   *     var dataUrl = canvas.toDataURL("image/jpeg", 0.95);
+   *     var dataUrl = canvas.toDataUrl("image/jpeg", 0.95);
    *     // The Data Uri would look similar to
    *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
    *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
@@ -6770,6 +6774,10 @@
   // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#dom-document-visibilitystate
   final String $dom_webkitVisibilityState;
 
+  @DomName('Document.adoptNode')
+  @DocsEditable
+  Node adoptNode(Node source) native;
+
   @JSName('caretRangeFromPoint')
   /// Use the [Range] constructor instead.
   @DomName('Document.caretRangeFromPoint')
@@ -6888,6 +6896,10 @@
   @Creates('NodeList')
   List<Node> getElementsByTagName(String tagname) native;
 
+  @DomName('Document.importNode')
+  @DocsEditable
+  Node importNode(Node importedNode, [bool deep]) native;
+
   @DomName('Document.queryCommandEnabled')
   @DocsEditable
   bool queryCommandEnabled(String command) native;
@@ -7624,7 +7636,7 @@
     : _childElements = element.$dom_children,
       _element = element;
 
-  bool contains(Element element) => _childElements.contains(element);
+  bool contains(Object element) => _childElements.contains(element);
 
 
   bool get isEmpty {
@@ -11990,7 +12002,7 @@
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Creates('ByteBuffer|Blob|Document|=Object|=List|String|num')
+  @Creates('ByteBuffer|Blob|Document|=Object|JSExtendableArray|String|num')
   final Object response;
 
   /**
@@ -13449,6 +13461,15 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+/**
+ * An event that describes user interaction with the keyboard.
+ *
+ * The [type] of the event identifies what kind of interaction occurred.
+ *
+ * See also:
+ *
+ * * [KeyboardEvent](https://developer.mozilla.org/en/DOM/KeyboardEvent) at MDN.
+ */
 @DomName('KeyboardEvent')
 class KeyboardEvent extends UIEvent native "KeyboardEvent" {
 
@@ -15129,7 +15150,7 @@
   @DomName('MessageEvent.ports')
   @DocsEditable
   @Unstable
-  @Creates('=List')
+  @Creates('JSExtendableArray')
   final List<MessagePort> ports;
 
   WindowBase get source => _convertNativeToDart_Window(this._get_source);
@@ -22512,7 +22533,7 @@
  *
  * To receive data on the WebSocket, register a listener for message events.
  *
- *     webSocket.on.message.add((MessageEvent e) {
+ *     webSocket.onMessage.listen((MessageEvent e) {
  *       receivedData(e.data);
  *     });
  *
@@ -27468,293 +27489,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-// This code is inspired by ChangeSummary:
-// https://github.com/rafaelw/ChangeSummary/blob/master/change_summary.js
-// ...which underlies MDV. Since we don't need the functionality of
-// ChangeSummary, we just implement what we need for data bindings.
-// This allows our implementation to be much simpler.
-
-// TODO(jmesserly): should we make these types stronger, and require
-// Observable objects? Currently, it is fine to say something like:
-//     var path = new PathObserver(123, '');
-//     print(path.value); // "123"
-//
-// Furthermore this degenerate case is allowed:
-//     var path = new PathObserver(123, 'foo.bar.baz.qux');
-//     print(path.value); // "null"
-//
-// Here we see that any invalid (i.e. not Observable) value will break the
-// path chain without producing an error or exception.
-//
-// Now the real question: should we do this? For the former case, the behavior
-// is correct but we could chose to handle it in the dart:html bindings layer.
-// For the latter case, it might be better to throw an error so users can find
-// the problem.
-
-
-/**
- * A data-bound path starting from a view-model or model object, for example
- * `foo.bar.baz`.
- *
- * When the [values] stream is being listened to, this will observe changes to
- * the object and any intermediate object along the path, and send [values]
- * accordingly. When all listeners are unregistered it will stop observing
- * the objects.
- *
- * This class is used to implement [Node.bind] and similar functionality.
- */
-// TODO(jmesserly): find a better home for this type.
-@Experimental
-class PathObserver {
-  /** The object being observed. */
-  final object;
-
-  /** The path string. */
-  final String path;
-
-  /** True if the path is valid, otherwise false. */
-  final bool _isValid;
-
-  // TODO(jmesserly): same issue here as ObservableMixin: is there an easier
-  // way to get a broadcast stream?
-  StreamController _values;
-  Stream _valueStream;
-
-  _PropertyObserver _observer, _lastObserver;
-
-  Object _lastValue;
-  bool _scheduled = false;
-
-  /**
-   * Observes [path] on [object] for changes. This returns an object that can be
-   * used to get the changes and get/set the value at this path.
-   * See [PathObserver.values] and [PathObserver.value].
-   */
-  PathObserver(this.object, String path)
-    : path = path, _isValid = _isPathValid(path) {
-
-    // TODO(jmesserly): if the path is empty, or the object is! Observable, we
-    // can optimize the PathObserver to be more lightweight.
-
-    _values = new StreamController.broadcast(sync: true,
-                                             onListen: _observe,
-                                             onCancel: _unobserve);
-
-    if (_isValid) {
-      var segments = [];
-      for (var segment in path.trim().split('.')) {
-        if (segment == '') continue;
-        var index = int.parse(segment, onError: (_) {});
-        segments.add(index != null ? index : new Symbol(segment));
-      }
-
-      // Create the property observer linked list.
-      // Note that the structure of a path can't change after it is initially
-      // constructed, even though the objects along the path can change.
-      for (int i = segments.length - 1; i >= 0; i--) {
-        _observer = new _PropertyObserver(this, segments[i], _observer);
-        if (_lastObserver == null) _lastObserver = _observer;
-      }
-    }
-  }
-
-  // TODO(jmesserly): we could try adding the first value to the stream, but
-  // that delivers the first record async.
-  /**
-   * Listens to the stream, and invokes the [callback] immediately with the
-   * current [value]. This is useful for bindings, which want to be up-to-date
-   * immediately.
-   */
-  StreamSubscription bindSync(void callback(value)) {
-    var result = values.listen(callback);
-    callback(value);
-    return result;
-  }
-
-  // TODO(jmesserly): should this be a change record with the old value?
-  // TODO(jmesserly): should this be a broadcast stream? We only need
-  // single-subscription in the bindings system, so single sub saves overhead.
-  /**
-   * Gets the stream of values that were observed at this path.
-   * This returns a single-subscription stream.
-   */
-  Stream get values => _values.stream;
-
-  /** Force synchronous delivery of [values]. */
-  void _deliverValues() {
-    _scheduled = false;
-
-    var newValue = value;
-    if (!identical(_lastValue, newValue)) {
-      _values.add(newValue);
-      _lastValue = newValue;
-    }
-  }
-
-  void _observe() {
-    if (_observer != null) {
-      _lastValue = value;
-      _observer.observe();
-    }
-  }
-
-  void _unobserve() {
-    if (_observer != null) _observer.unobserve();
-  }
-
-  void _notifyChange() {
-    if (_scheduled) return;
-    _scheduled = true;
-
-    // TODO(jmesserly): should we have a guarenteed order with respect to other
-    // paths? If so, we could implement this fairly easily by sorting instances
-    // of this class by birth order before delivery.
-    queueChangeRecords(_deliverValues);
-  }
-
-  /** Gets the last reported value at this path. */
-  get value {
-    if (!_isValid) return null;
-    if (_observer == null) return object;
-    _observer.ensureValue(object);
-    return _lastObserver.value;
-  }
-
-  /** Sets the value at this path. */
-  void set value(Object value) {
-    // TODO(jmesserly): throw if property cannot be set?
-    // MDV seems tolerant of these error.
-    if (_observer == null || !_isValid) return;
-    _observer.ensureValue(object);
-    var last = _lastObserver;
-    if (_setObjectProperty(last._object, last._property, value)) {
-      // Technically, this would get updated asynchronously via a change record.
-      // However, it is nice if calling the getter will yield the same value
-      // that was just set. So we use this opportunity to update our cache.
-      last.value = value;
-    }
-  }
-}
-
-// TODO(jmesserly): these should go away in favor of mirrors!
-_getObjectProperty(object, property) {
-  if (object is List && property is int) {
-    if (property >= 0 && property < object.length) {
-      return object[property];
-    } else {
-      return null;
-    }
-  }
-
-  // TODO(jmesserly): what about length?
-  if (object is Map) return object[property];
-
-  if (object is Observable) return object.getValueWorkaround(property);
-
-  return null;
-}
-
-bool _setObjectProperty(object, property, value) {
-  if (object is List && property is int) {
-    object[property] = value;
-  } else if (object is Map) {
-    object[property] = value;
-  } else if (object is Observable) {
-    (object as Observable).setValueWorkaround(property, value);
-  } else {
-    return false;
-  }
-  return true;
-}
-
-
-class _PropertyObserver {
-  final PathObserver _path;
-  final _property;
-  final _PropertyObserver _next;
-
-  // TODO(jmesserly): would be nice not to store both of these.
-  Object _object;
-  Object _value;
-  StreamSubscription _sub;
-
-  _PropertyObserver(this._path, this._property, this._next);
-
-  get value => _value;
-
-  void set value(Object newValue) {
-    _value = newValue;
-    if (_next != null) {
-      if (_sub != null) _next.unobserve();
-      _next.ensureValue(_value);
-      if (_sub != null) _next.observe();
-    }
-  }
-
-  void ensureValue(object) {
-    // If we're observing, values should be up to date already.
-    if (_sub != null) return;
-
-    _object = object;
-    value = _getObjectProperty(object, _property);
-  }
-
-  void observe() {
-    if (_object is Observable) {
-      assert(_sub == null);
-      _sub = (_object as Observable).changes.listen(_onChange);
-    }
-    if (_next != null) _next.observe();
-  }
-
-  void unobserve() {
-    if (_sub == null) return;
-
-    _sub.cancel();
-    _sub = null;
-    if (_next != null) _next.unobserve();
-  }
-
-  void _onChange(List<ChangeRecord> changes) {
-    for (var change in changes) {
-      // TODO(jmesserly): what to do about "new Symbol" here?
-      // Ideally this would only preserve names if the user has opted in to
-      // them being preserved.
-      // TODO(jmesserly): should we drop observable maps with String keys?
-      // If so then we only need one check here.
-      if (change.changes(_property)) {
-        value = _getObjectProperty(_object, _property);
-        _path._notifyChange();
-        return;
-      }
-    }
-  }
-}
-
-// From: https://github.com/rafaelw/ChangeSummary/blob/master/change_summary.js
-
-const _pathIndentPart = r'[$a-z0-9_]+[$a-z0-9_\d]*';
-final _pathRegExp = new RegExp('^'
-    '(?:#?' + _pathIndentPart + ')?'
-    '(?:'
-      '(?:\\.' + _pathIndentPart + ')'
-    ')*'
-    r'$', caseSensitive: false);
-
-final _spacesRegExp = new RegExp(r'\s');
-
-bool _isPathValid(String s) {
-  s = s.replaceAll(_spacesRegExp, '');
-
-  if (s == '') return true;
-  if (s[0] == '.') return false;
-  return _pathRegExp.hasMatch(s);
-}
-// 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.
-
-
 /**
  * A utility class for representing two-dimensional positions.
  */
@@ -29433,9 +29167,9 @@
 
   void sort([int compare(E a, E b)]) { _list.sort(compare); }
 
-  int indexOf(E element, [int start = 0]) => _list.indexOf(element, start);
+  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);
 
-  int lastIndexOf(E element, [int start]) => _list.lastIndexOf(element, start);
+  int lastIndexOf(Object element, [int start]) => _list.lastIndexOf(element, start);
 
   void insert(int index, E element) => _list.insert(index, element);
 
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index a97473f..0e28ef6 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -1,4 +1,8 @@
 /// The Dart HTML library.
+///
+/// For examples, see
+/// [Dart HTML5 Samples](https://github.com/dart-lang/dart-html5-samples)
+/// on Github.
 library dart.dom.html;
 
 import 'dart:async';
@@ -1057,7 +1061,7 @@
    *     var ctx = canvas.context2D
    *     ..fillStyle = "rgb(200,0,0)"
    *     ..fillRect(10, 10, 55, 50);
-   *     var dataUrl = canvas.toDataURL("image/jpeg", 0.95);
+   *     var dataUrl = canvas.toDataUrl("image/jpeg", 0.95);
    *     // The Data Uri would look similar to
    *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
    *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
@@ -7326,6 +7330,10 @@
   // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#dom-document-visibilitystate
   String get $dom_webkitVisibilityState native "Document_webkitVisibilityState_Getter";
 
+  @DomName('Document.adoptNode')
+  @DocsEditable
+  Node adoptNode(Node source) native "Document_adoptNode_Callback";
+
   /// Use the [Range] constructor instead.
   @DomName('Document.caretRangeFromPoint')
   @DocsEditable
@@ -7436,6 +7444,17 @@
   @DocsEditable
   List<Node> getElementsByTagName(String tagname) native "Document_getElementsByTagName_Callback";
 
+  Node importNode(Node importedNode, [bool deep]) {
+    if (deep != null) {
+      return _importNode_1(importedNode, deep);
+    }
+    return _importNode_2(importedNode);
+  }
+
+  Node _importNode_1(importedNode, deep) native "Document__importNode_1_Callback";
+
+  Node _importNode_2(importedNode) native "Document__importNode_2_Callback";
+
   @DomName('Document.queryCommandEnabled')
   @DocsEditable
   bool queryCommandEnabled(String command) native "Document_queryCommandEnabled_Callback";
@@ -8182,7 +8201,7 @@
     : _childElements = element.$dom_children,
       _element = element;
 
-  bool contains(Element element) => _childElements.contains(element);
+  bool contains(Object element) => _childElements.contains(element);
 
 
   bool get isEmpty {
@@ -24422,7 +24441,7 @@
  *
  * To receive data on the WebSocket, register a listener for message events.
  *
- *     webSocket.on.message.add((MessageEvent e) {
+ *     webSocket.onMessage.listen((MessageEvent e) {
  *       receivedData(e.data);
  *     });
  *
@@ -29464,293 +29483,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-// This code is inspired by ChangeSummary:
-// https://github.com/rafaelw/ChangeSummary/blob/master/change_summary.js
-// ...which underlies MDV. Since we don't need the functionality of
-// ChangeSummary, we just implement what we need for data bindings.
-// This allows our implementation to be much simpler.
-
-// TODO(jmesserly): should we make these types stronger, and require
-// Observable objects? Currently, it is fine to say something like:
-//     var path = new PathObserver(123, '');
-//     print(path.value); // "123"
-//
-// Furthermore this degenerate case is allowed:
-//     var path = new PathObserver(123, 'foo.bar.baz.qux');
-//     print(path.value); // "null"
-//
-// Here we see that any invalid (i.e. not Observable) value will break the
-// path chain without producing an error or exception.
-//
-// Now the real question: should we do this? For the former case, the behavior
-// is correct but we could chose to handle it in the dart:html bindings layer.
-// For the latter case, it might be better to throw an error so users can find
-// the problem.
-
-
-/**
- * A data-bound path starting from a view-model or model object, for example
- * `foo.bar.baz`.
- *
- * When the [values] stream is being listened to, this will observe changes to
- * the object and any intermediate object along the path, and send [values]
- * accordingly. When all listeners are unregistered it will stop observing
- * the objects.
- *
- * This class is used to implement [Node.bind] and similar functionality.
- */
-// TODO(jmesserly): find a better home for this type.
-@Experimental
-class PathObserver {
-  /** The object being observed. */
-  final object;
-
-  /** The path string. */
-  final String path;
-
-  /** True if the path is valid, otherwise false. */
-  final bool _isValid;
-
-  // TODO(jmesserly): same issue here as ObservableMixin: is there an easier
-  // way to get a broadcast stream?
-  StreamController _values;
-  Stream _valueStream;
-
-  _PropertyObserver _observer, _lastObserver;
-
-  Object _lastValue;
-  bool _scheduled = false;
-
-  /**
-   * Observes [path] on [object] for changes. This returns an object that can be
-   * used to get the changes and get/set the value at this path.
-   * See [PathObserver.values] and [PathObserver.value].
-   */
-  PathObserver(this.object, String path)
-    : path = path, _isValid = _isPathValid(path) {
-
-    // TODO(jmesserly): if the path is empty, or the object is! Observable, we
-    // can optimize the PathObserver to be more lightweight.
-
-    _values = new StreamController.broadcast(sync: true,
-                                             onListen: _observe,
-                                             onCancel: _unobserve);
-
-    if (_isValid) {
-      var segments = [];
-      for (var segment in path.trim().split('.')) {
-        if (segment == '') continue;
-        var index = int.parse(segment, onError: (_) {});
-        segments.add(index != null ? index : new Symbol(segment));
-      }
-
-      // Create the property observer linked list.
-      // Note that the structure of a path can't change after it is initially
-      // constructed, even though the objects along the path can change.
-      for (int i = segments.length - 1; i >= 0; i--) {
-        _observer = new _PropertyObserver(this, segments[i], _observer);
-        if (_lastObserver == null) _lastObserver = _observer;
-      }
-    }
-  }
-
-  // TODO(jmesserly): we could try adding the first value to the stream, but
-  // that delivers the first record async.
-  /**
-   * Listens to the stream, and invokes the [callback] immediately with the
-   * current [value]. This is useful for bindings, which want to be up-to-date
-   * immediately.
-   */
-  StreamSubscription bindSync(void callback(value)) {
-    var result = values.listen(callback);
-    callback(value);
-    return result;
-  }
-
-  // TODO(jmesserly): should this be a change record with the old value?
-  // TODO(jmesserly): should this be a broadcast stream? We only need
-  // single-subscription in the bindings system, so single sub saves overhead.
-  /**
-   * Gets the stream of values that were observed at this path.
-   * This returns a single-subscription stream.
-   */
-  Stream get values => _values.stream;
-
-  /** Force synchronous delivery of [values]. */
-  void _deliverValues() {
-    _scheduled = false;
-
-    var newValue = value;
-    if (!identical(_lastValue, newValue)) {
-      _values.add(newValue);
-      _lastValue = newValue;
-    }
-  }
-
-  void _observe() {
-    if (_observer != null) {
-      _lastValue = value;
-      _observer.observe();
-    }
-  }
-
-  void _unobserve() {
-    if (_observer != null) _observer.unobserve();
-  }
-
-  void _notifyChange() {
-    if (_scheduled) return;
-    _scheduled = true;
-
-    // TODO(jmesserly): should we have a guarenteed order with respect to other
-    // paths? If so, we could implement this fairly easily by sorting instances
-    // of this class by birth order before delivery.
-    queueChangeRecords(_deliverValues);
-  }
-
-  /** Gets the last reported value at this path. */
-  get value {
-    if (!_isValid) return null;
-    if (_observer == null) return object;
-    _observer.ensureValue(object);
-    return _lastObserver.value;
-  }
-
-  /** Sets the value at this path. */
-  void set value(Object value) {
-    // TODO(jmesserly): throw if property cannot be set?
-    // MDV seems tolerant of these error.
-    if (_observer == null || !_isValid) return;
-    _observer.ensureValue(object);
-    var last = _lastObserver;
-    if (_setObjectProperty(last._object, last._property, value)) {
-      // Technically, this would get updated asynchronously via a change record.
-      // However, it is nice if calling the getter will yield the same value
-      // that was just set. So we use this opportunity to update our cache.
-      last.value = value;
-    }
-  }
-}
-
-// TODO(jmesserly): these should go away in favor of mirrors!
-_getObjectProperty(object, property) {
-  if (object is List && property is int) {
-    if (property >= 0 && property < object.length) {
-      return object[property];
-    } else {
-      return null;
-    }
-  }
-
-  // TODO(jmesserly): what about length?
-  if (object is Map) return object[property];
-
-  if (object is Observable) return object.getValueWorkaround(property);
-
-  return null;
-}
-
-bool _setObjectProperty(object, property, value) {
-  if (object is List && property is int) {
-    object[property] = value;
-  } else if (object is Map) {
-    object[property] = value;
-  } else if (object is Observable) {
-    (object as Observable).setValueWorkaround(property, value);
-  } else {
-    return false;
-  }
-  return true;
-}
-
-
-class _PropertyObserver {
-  final PathObserver _path;
-  final _property;
-  final _PropertyObserver _next;
-
-  // TODO(jmesserly): would be nice not to store both of these.
-  Object _object;
-  Object _value;
-  StreamSubscription _sub;
-
-  _PropertyObserver(this._path, this._property, this._next);
-
-  get value => _value;
-
-  void set value(Object newValue) {
-    _value = newValue;
-    if (_next != null) {
-      if (_sub != null) _next.unobserve();
-      _next.ensureValue(_value);
-      if (_sub != null) _next.observe();
-    }
-  }
-
-  void ensureValue(object) {
-    // If we're observing, values should be up to date already.
-    if (_sub != null) return;
-
-    _object = object;
-    value = _getObjectProperty(object, _property);
-  }
-
-  void observe() {
-    if (_object is Observable) {
-      assert(_sub == null);
-      _sub = (_object as Observable).changes.listen(_onChange);
-    }
-    if (_next != null) _next.observe();
-  }
-
-  void unobserve() {
-    if (_sub == null) return;
-
-    _sub.cancel();
-    _sub = null;
-    if (_next != null) _next.unobserve();
-  }
-
-  void _onChange(List<ChangeRecord> changes) {
-    for (var change in changes) {
-      // TODO(jmesserly): what to do about "new Symbol" here?
-      // Ideally this would only preserve names if the user has opted in to
-      // them being preserved.
-      // TODO(jmesserly): should we drop observable maps with String keys?
-      // If so then we only need one check here.
-      if (change.changes(_property)) {
-        value = _getObjectProperty(_object, _property);
-        _path._notifyChange();
-        return;
-      }
-    }
-  }
-}
-
-// From: https://github.com/rafaelw/ChangeSummary/blob/master/change_summary.js
-
-const _pathIndentPart = r'[$a-z0-9_]+[$a-z0-9_\d]*';
-final _pathRegExp = new RegExp('^'
-    '(?:#?' + _pathIndentPart + ')?'
-    '(?:'
-      '(?:\\.' + _pathIndentPart + ')'
-    ')*'
-    r'$', caseSensitive: false);
-
-final _spacesRegExp = new RegExp(r'\s');
-
-bool _isPathValid(String s) {
-  s = s.replaceAll(_spacesRegExp, '');
-
-  if (s == '') return true;
-  if (s[0] == '.') return false;
-  return _pathRegExp.hasMatch(s);
-}
-// 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.
-
-
 /**
  * A utility class for representing two-dimensional positions.
  */
@@ -30847,9 +30579,9 @@
 
   void sort([int compare(E a, E b)]) { _list.sort(compare); }
 
-  int indexOf(E element, [int start = 0]) => _list.indexOf(element, start);
+  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);
 
-  int lastIndexOf(E element, [int start]) => _list.lastIndexOf(element, start);
+  int lastIndexOf(Object element, [int start]) => _list.lastIndexOf(element, start);
 
   void insert(int index, E element) => _list.insert(index, element);
 
diff --git a/sdk/lib/html/html_common/conversions.dart b/sdk/lib/html/html_common/conversions.dart
index 12591d5..b387f41 100644
--- a/sdk/lib/html/html_common/conversions.dart
+++ b/sdk/lib/html/html_common/conversions.dart
@@ -34,7 +34,8 @@
 Map convertNativeToDart_Dictionary(object) {
   if (object == null) return null;
   var dict = {};
-  for (final key in JS('=List', 'Object.getOwnPropertyNames(#)', object)) {
+  var keys = JS('JSExtendableArray', 'Object.getOwnPropertyNames(#)', object);
+  for (final key in keys) {
     dict[key] = JS('var', '#[#]', object, key);
   }
   return dict;
@@ -165,7 +166,7 @@
       var copy = readSlot(slot);
       if (copy != null) {
         if (true == copy) {  // Cycle, so commit to making a copy.
-          copy = JS('=List', 'new Array(#)', length);
+          copy = JS('JSExtendableArray', 'new Array(#)', length);
           writeSlot(slot, copy);
         }
         return copy;
@@ -175,7 +176,7 @@
 
       // Always clone the list, as it may have non-native properties or methods
       // from interceptors and such.
-      copy = JS('=List', 'new Array(#)', length);
+      copy = JS('JSExtendableArray', 'new Array(#)', length);
       writeSlot(slot, copy);
 
       for ( ; i < length; i++) {
@@ -254,7 +255,7 @@
       copy = {};
 
       writeSlot(slot, copy);
-      for (final key in JS('=List', 'Object.keys(#)', e)) {
+      for (final key in JS('JSExtendableArray', 'Object.keys(#)', e)) {
         copy[key] = walk(JS('var', '#[#]', e, key));
       }
       return copy;
@@ -268,7 +269,7 @@
       int length = e.length;
       // Since a JavaScript Array is an instance of Dart List, we can modify it
       // in-place unless we must copy.
-      copy = mustCopy ? JS('=List', 'new Array(#)', length) : e;
+      copy = mustCopy ? JS('JSExtendableArray', 'new Array(#)', length) : e;
       writeSlot(slot, copy);
 
       for (int i = 0; i < length; i++) {
@@ -342,7 +343,7 @@
 
 const String _serializedScriptValue =
     'num|String|bool|'
-    '=List|=Object|'
+    'JSExtendableArray|=Object|'
     'Blob|File|ByteBuffer|TypedData'
     // TODO(sra): Add Date, RegExp.
     ;
diff --git a/sdk/lib/html/html_common/css_class_set.dart b/sdk/lib/html/html_common/css_class_set.dart
index ab17d10..18a80e71 100644
--- a/sdk/lib/html/html_common/css_class_set.dart
+++ b/sdk/lib/html/html_common/css_class_set.dart
@@ -174,9 +174,9 @@
   Iterable<String> skip(int n) => readClasses().skip(n);
   Iterable<String> skipWhile(bool test(String value)) =>
       readClasses().skipWhile(test);
-  String firstWhere(bool test(String value), { String orElse() }) =>
+  dynamic firstWhere(bool test(String value), { Object orElse() }) =>
       readClasses().firstWhere(test, orElse: orElse);
-  String lastWhere(bool test(String value), {String orElse()}) =>
+  dynamic lastWhere(bool test(String value), { Object orElse()}) =>
       readClasses().lastWhere(test, orElse: orElse);
   String singleWhere(bool test(String value)) =>
       readClasses().singleWhere(test);
diff --git a/sdk/lib/html/html_common/filtered_element_list.dart b/sdk/lib/html/html_common/filtered_element_list.dart
index 61954e6..64326a4 100644
--- a/sdk/lib/html/html_common/filtered_element_list.dart
+++ b/sdk/lib/html/html_common/filtered_element_list.dart
@@ -59,8 +59,10 @@
     }
   }
 
-  bool contains(Element element) {
-    return (element != null) && (element.parentNode == _node);
+  bool contains(Object needle) {
+    if (needle is! Element) return false;
+    Element element = needle;
+    return element.parentNode == _node;
   }
 
   Iterable<Element> get reversed => _filtered.reversed;
diff --git a/sdk/lib/html/html_common/html_common_dart2js.dart b/sdk/lib/html/html_common/html_common_dart2js.dart
index ed42991..dbf9352 100644
--- a/sdk/lib/html/html_common/html_common_dart2js.dart
+++ b/sdk/lib/html/html_common/html_common_dart2js.dart
@@ -9,6 +9,7 @@
 import 'dart:typed_data';
 import 'dart:_js_helper' show Creates, Returns;
 import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show JSExtendableArray;
 
 import 'metadata.dart';
 export 'metadata.dart';
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index 9dd0d9a..e8ab65e 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -6,6 +6,7 @@
 import 'dart:typed_data';
 import 'dart:_js_helper' show Creates, Returns, JSName, Null;
 import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show JSExtendableArray;
 // Copyright (c) 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.
@@ -128,8 +129,8 @@
   return convertNativeToDart_AcceptStructuredClone(object, mustCopy: false);
 }
 
-
-const String _idbKey = '=List|=Object|num|String';  // TODO(sra): Add DateTime.
+// TODO(sra): Add DateTime.
+const String _idbKey = 'JSExtendableArray|=Object|num|String';
 const _annotation_Creates_IDBKey = const Creates(_idbKey);
 const _annotation_Returns_IDBKey = const Returns(_idbKey);
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index f47ef4f..4472fcb 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -237,16 +237,35 @@
     return new Directory(newPath);
   }
 
+  static String _trimTrailingPathSeparators(String path) {
+    // Don't handle argument errors here.
+    if (path is! String) return path;
+    if (Platform.operatingSystem == 'windows') {
+      while (path.length > 1 &&
+             (path.endsWith(Platform.pathSeparator) ||
+              path.endsWith('/'))) {
+        path = path.substring(0, path.length - 1);
+      }
+    } else {
+      while (path.length > 1 && path.endsWith(Platform.pathSeparator)) {
+        path = path.substring(0, path.length - 1);
+      }
+    }
+    return path;
+  }
+
   Stream<FileSystemEntity> list({bool recursive: false,
                                  bool followLinks: true}) {
-    return new _AsyncDirectoryLister(path, recursive, followLinks).stream;
+    return new _AsyncDirectoryLister(_trimTrailingPathSeparators(path),
+                                     recursive,
+                                     followLinks).stream;
   }
 
   List listSync({bool recursive: false, bool followLinks: true}) {
-    if (_path is! String || recursive is! bool) {
+    if (_path is! String || recursive is! bool || followLinks is! bool) {
       throw new ArgumentError();
     }
-    return _list(_path, recursive, followLinks);
+    return _list(_trimTrailingPathSeparators(path), recursive, followLinks);
   }
 
   String get path => _path;
@@ -308,7 +327,8 @@
                         bool this.followLinks) {
     controller = new StreamController(onListen: onListen,
                                       onResume: onResume,
-                                      onCancel: onCancel);
+                                      onCancel: onCancel,
+                                      sync: true);
   }
 
   Stream get stream => controller.stream;
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index 7a59c19..1fc9a17 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -994,10 +994,12 @@
 
 // Transformer that transforms data to HTTP Chunked Encoding.
 class _ChunkedTransformer extends StreamEventTransformer<List<int>, List<int>> {
+  int _pendingFooter = 0;
+
   void handleData(List<int> data, EventSink<List<int>> sink) {
     sink.add(_chunkHeader(data.length));
     if (data.length > 0) sink.add(data);
-    sink.add(_chunkFooter);
+    _pendingFooter = 2;
   }
 
   void handleDone(EventSink<List<int>> sink) {
@@ -1005,25 +1007,41 @@
     sink.close();
   }
 
-  static List<int> _chunkHeader(int length) {
+  List<int> _chunkHeader(int length) {
     const hexDigits = const [0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
                              0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46];
-    var header = [];
     if (length == 0) {
-      header.add(hexDigits[length]);
-    } else {
-      while (length > 0) {
-        header.insert(0, hexDigits[length % 16]);
-        length = length >> 4;
-      }
+      if (_pendingFooter == 2) return _footerAndChunk0Length;
+      return _chunk0Length;
     }
-    header.add(_CharCode.CR);
-    header.add(_CharCode.LF);
-    return header;
+    int size = _pendingFooter;
+    int len = length;
+    // Compute a fast integer version of (log(length + 1) / log(16)).ceil().
+    while (len > 0) {
+      size++;
+      len >>= 4;
+    }
+    var footerAndHeader = new Uint8List(size + 2);
+    if (_pendingFooter == 2) {
+      footerAndHeader[0] = _CharCode.CR;
+      footerAndHeader[1] = _CharCode.LF;
+    }
+    int index = size;
+    while (index > _pendingFooter) {
+      footerAndHeader[--index] = hexDigits[length & 15];
+      length = length >> 4;
+    }
+    footerAndHeader[size + 0] = _CharCode.CR;
+    footerAndHeader[size + 1] = _CharCode.LF;
+    return footerAndHeader;
   }
 
-  // Footer is just a CRLF.
-  static List<int> get _chunkFooter => const [_CharCode.CR, _CharCode.LF];
+  static List<int> get _footerAndChunk0Length => new Uint8List.fromList(
+      const [_CharCode.CR, _CharCode.LF, 0x30, _CharCode.CR, _CharCode.LF,
+             _CharCode.CR, _CharCode.LF]);
+
+  static List<int> get _chunk0Length => new Uint8List.fromList(
+      const [0x30, _CharCode.CR, _CharCode.LF, _CharCode.CR, _CharCode.LF]);
 }
 
 
@@ -2364,7 +2382,7 @@
 }
 
 String _getHttpVersion() {
-  var version = new Options().version;
+  var version = Platform.version;
   // Only include major and minor version numbers.
   int index = version.indexOf('.', version.indexOf('.') + 1);
   version = version.substring(0, index);
diff --git a/sdk/lib/io/http_parser.dart b/sdk/lib/io/http_parser.dart
index f863e4fc..d885008 100644
--- a/sdk/lib/io/http_parser.dart
+++ b/sdk/lib/io/http_parser.dart
@@ -660,7 +660,7 @@
           _index--;
           int dataAvailable = _buffer.length - _index;
           List<int> data;
-          if (_remainingContent == null ||
+          if (_remainingContent == -1 ||
               dataAvailable <= _remainingContent) {
             if (_index == 0) {
               data = _buffer;
@@ -673,7 +673,7 @@
             data.setRange(0, _remainingContent, _buffer, _index);
           }
           _bodyController.add(data);
-          if (_remainingContent != null) {
+          if (_remainingContent != -1) {
             _remainingContent -= data.length;
           }
           _index += data.length;
@@ -814,6 +814,8 @@
     _method_or_status_code = new List();
     _uri_or_reason_phrase = new List();
 
+    _statusCode = 0;
+
     _httpVersion = _HttpVersion.UNDETERMINED;
     _transferLength = -1;
     _persistentConnection = false;
@@ -822,7 +824,7 @@
 
     _noMessageBody = false;
     _responseToMethod = null;
-    _remainingContent = null;
+    _remainingContent = -1;
 
     _headers = null;
   }
@@ -961,21 +963,21 @@
   int _state;
   int _httpVersionIndex;
   int _messageType;
-  int _statusCode;
+  int _statusCode = 0;
   List _method_or_status_code;
   List _uri_or_reason_phrase;
   List _headerField;
   List _headerValue;
 
   int _httpVersion;
-  int _transferLength;
+  int _transferLength = -1;
   bool _persistentConnection;
   bool _connectionUpgrade;
   bool _chunked;
 
   bool _noMessageBody;
   String _responseToMethod;  // Indicates the method used for the request.
-  int _remainingContent;
+  int _remainingContent = -1;
 
   _HttpHeaders _headers;
 
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index 955622f..e8c4a49 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -146,7 +146,7 @@
       target = _makeWindowsLinkTarget(target);
     }
     var result = _File._createLink(path, target);
-    throwIfError(result, "Cannot create link '$path'");
+    throwIfError(result, "Cannot create link", path);
   }
 
   // Put target into the form "\??\C:\my\target\dir".
@@ -155,12 +155,16 @@
       return target;
     }
     if (!(target.length > 3 && target[1] == ':' && target[2] == '\\')) {
-      target = new File(target).fullPathSync();
+      try {
+        target = new File(target).fullPathSync();
+      } catch (e) {
+        throw new LinkException('Could not locate target', target, e.osError);
+      }
     }
     if (target.length > 3 && target[1] == ':' && target[2] == '\\') {
       target = '\\??\\$target';
     } else {
-      throw new ArgumentError(
+      throw new LinkException(
           'Target $target of Link.create on Windows cannot be converted' +
           ' to start with a drive letter.  Unexpected error.');
     }
@@ -188,7 +192,7 @@
 
   void deleteSync() {
     var result = _File._deleteLink(path);
-    throwIfError(result, "Cannot delete link '$path'");
+    throwIfError(result, "Cannot delete link", path);
   }
 
   Future<String> target() {
@@ -207,13 +211,13 @@
 
   String targetSync() {
     var result = _File._linkTarget(path);
-    throwIfError(result, "Cannot read link '$path'");
+    throwIfError(result, "Cannot read link", path);
     return result;
   }
 
-  static throwIfError(Object result, String msg) {
+  static throwIfError(Object result, String msg, [String path = ""]) {
     if (result is OSError) {
-      throw new LinkException(msg, result);
+      throw new LinkException(msg, path, result);
     }
   }
 
@@ -245,8 +249,8 @@
 
 class LinkException implements IOException {
   const LinkException([String this.message = "",
-                         String this.path = "",
-                         OSError this.osError = null]);
+                       String this.path = "",
+                       OSError this.osError = null]);
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write("LinkException");
diff --git a/sdk/lib/io/options.dart b/sdk/lib/io/options.dart
index 7b483e5..08dd129 100644
--- a/sdk/lib/io/options.dart
+++ b/sdk/lib/io/options.dart
@@ -44,12 +44,17 @@
 
 
   /**
-   * Returns the version of the current dart runtime.
+   * Returns the version of the current Dart runtime.
    */
   String get version;
 }
 
 class _OptionsImpl implements Options {
+  List<String> _arguments = null;
+
+  // This arguments singleton is written to by the embedder if applicable.
+  static List<String> _nativeArguments = const [];
+
   List<String> get arguments {
     if (_arguments == null) {
       // On first access make a copy of the native arguments.
@@ -58,24 +63,7 @@
     return _arguments;
   }
 
-  String get executable {
-    return _nativeExecutable;
-  }
-
-  String get script {
-    return _nativeScript;
-  }
-
-  external String get version;
-
-  List<String> _arguments = null;
-
-  // This arguments singleton is written to by the embedder if applicable.
-  static List<String> _nativeArguments = const [];
-
-  // This executable singleton is written to by the embedder if applicable.
-  static String _nativeExecutable = '';
-
-  // This script singleton is written to by the embedder if applicable.
-  static String _nativeScript = '';
+  String get executable => Platform.executable;
+  String get script => Platform.script;
+  String get version => Platform.version;
 }
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index 156238a..90fe65a 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -9,27 +9,59 @@
  * system.
  */
 class Platform {
+  static final _numberOfProcessors = _Platform.numberOfProcessors;
+  static final _pathSeparator = _Platform.pathSeparator;
+  static final _operatingSystem = _Platform.operatingSystem;
+  static final _localHostname = _Platform.localHostname;
+  static final _version = _Platform.version;
+
+  // This executable singleton is written to by the embedder if applicable.
+  static String _nativeExecutable = '';
+
+  // This script singleton is written to by the embedder if applicable.
+  static String _nativeScript = '';
+
   /**
    * Get the number of processors of the machine.
    */
-  static int get numberOfProcessors => _Platform.numberOfProcessors;
+  static int get numberOfProcessors => _numberOfProcessors;
 
   /**
    * Get the path separator used by the operating system to separate
    * components in file paths.
    */
-  static String get pathSeparator => _Platform.pathSeparator;
+  static String get pathSeparator => _pathSeparator;
 
   /**
-   * Get a string ('macos', 'windows', 'linux') representing the
-   * operating system.
+   * Get a string (`linux`, `macos`, `windows` or `android`)
+   * representing the operating system.
    */
-  static String get operatingSystem => _Platform.operatingSystem;
+  static String get operatingSystem => _operatingSystem;
 
   /**
    * Get the local hostname for the system.
    */
-  static String get localHostname => _Platform.localHostname;
+  static String get localHostname => _localHostname;
+
+  /**
+   * Returns true if the operating system is Linux.
+   */
+  static bool get isLinux => _operatingSystem == "linux";
+
+  /**
+   * Returns true if the operating system is Mac OS.
+   */
+  static bool get isMacOS => _operatingSystem == "macos";
+
+  /**
+   * Returns true if the operating system is Windows.
+   */
+  static bool get isWindows => _operatingSystem == "windows";
+
+  /**
+   * Returns true if the operating system is Android.
+   */
+  static bool get isAndroid => _operatingSystem == "android";
 
   /**
    * Get the environment for this process.
@@ -40,4 +72,27 @@
    * a standard case-sensitive map.
    */
   static Map<String, String> get environment => _Platform.environment;
+
+  /**
+   * Returns the path of the executable used to run the script in this
+   * isolate.
+   *
+   * If the execution environment does not support [executable] an empty
+   * string is returned.
+   */
+  static String get executable => _nativeExecutable;
+
+  /**
+   * Returns the path of the script being run in this isolate.
+   *
+   * If the executable environment does not support [script] an empty
+   * string is returned.
+   */
+  static String get script => _nativeScript;
+
+
+  /**
+   * Returns the version of the current Dart runtime.
+   */
+  static String get version => _version;
 }
diff --git a/sdk/lib/io/platform_impl.dart b/sdk/lib/io/platform_impl.dart
index 89fc2a0..b9bae78 100644
--- a/sdk/lib/io/platform_impl.dart
+++ b/sdk/lib/io/platform_impl.dart
@@ -10,18 +10,11 @@
   external static String _operatingSystem();
   external static _localHostname();
   external static _environment();
+  external static String _version();
 
-  static int get numberOfProcessors {
-    return _numberOfProcessors();
-  }
-
-  static String get pathSeparator {
-    return _pathSeparator();
-  }
-
-  static String get operatingSystem {
-    return _operatingSystem();
-  }
+  static int get numberOfProcessors => _numberOfProcessors();
+  static String get pathSeparator => _pathSeparator();
+  static String get operatingSystem => _operatingSystem();
 
   static String get localHostname {
     var result = _localHostname();
@@ -57,6 +50,8 @@
       return result;
     }
   }
+
+  static String get version => _version();
 }
 
 // Environment variables are case-insensitive on Windows. In order
@@ -72,7 +67,7 @@
   }
 
   bool containsKey(String key) => _map.containsKey(key.toUpperCase());
-  bool containsValue(V value) => _map.containsValue(value);
+  bool containsValue(Object value) => _map.containsValue(value);
   V operator [](String key) => _map[key.toUpperCase()];
   void operator []=(String key, V value) {
     _map[key.toUpperCase()] = value;
diff --git a/sdk/lib/io/process.dart b/sdk/lib/io/process.dart
index 6c79c12..456d215 100644
--- a/sdk/lib/io/process.dart
+++ b/sdk/lib/io/process.dart
@@ -83,6 +83,10 @@
    * if an environment variable with code-points outside the US-ASCII range is
    * passed in.
    *
+   * If [includeParentEnvironment] is `true`, the process's environment will
+   * include the parent process's environment, with [environment] taking
+   * precedence. Default is `true`.
+   *
    * If [runInShell] is true, the process will be spawned through a system
    * shell. On Linux and Mac OS, [:/bin/sh:] is used, while
    * [:%WINDIR%\system32\cmd.exe:] is used on Windows.
@@ -97,6 +101,7 @@
       List<String> arguments,
       {String workingDirectory,
        Map<String, String> environment,
+       bool includeParentEnvironment: true,
        bool runInShell: false});
 
   /**
@@ -114,6 +119,10 @@
    * if an environment variable with code-points outside the US-ASCII range is
    * passed in.
    *
+   * If [includeParentEnvironment] is `true`, the process's environment will
+   * include the parent process's environment, with [environment] taking
+   * precedence. Default is `true`.
+   *
    * If [runInShell] is true, the process will be spawned through a system
    * shell. On Linux and Mac OS, `/bin/sh` is used, while
    * `%WINDIR%\system32\cmd.exe` is used on Windows.
@@ -133,6 +142,7 @@
       List<String> arguments,
       {String workingDirectory,
        Map<String, String> environment,
+       bool includeParentEnvironment: true,
        bool runInShell: false,
        Encoding stdoutEncoding: Encoding.SYSTEM,
        Encoding stderrEncoding: Encoding.SYSTEM});
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index d6f5734..8733f32 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -57,7 +57,7 @@
    *
    * If the [socket] already has a subscription, this subscription
    * will no longer receive and events. In most cases calling
-   * [:pause:] on this subscription before starting TLS handshake is
+   * `pause` on this subscription before starting TLS handshake is
    * the right thing to do.
    *
    * If the [host] argument is passed it will be used as the host name
@@ -65,6 +65,12 @@
    * the [socket] will be used. The [host] can be either a [String] or
    * an [InternetAddress].
    *
+   * Calling this function will _not_ cause a DNS host lookup. If the
+   * [host] passed is a [String] the [InternetAddress] for the
+   * resulting [SecureSocket] will have the passed in [host] as its
+   * host value and the internet address of the already connected
+   * socket as its address value.
+   *
    * See [connect] for more information on the arguments.
    *
    */
@@ -144,16 +150,18 @@
   X509Certificate get peerCertificate;
 
   /**
-   * Initializes the NSS library.  If [initialize] is not called, the library
+   * Initializes the NSS library. If [initialize] is not called, the library
    * is automatically initialized as if [initialize] were called with no
-   * arguments.
+   * arguments. If [initialize] is called more than once, or called after
+   * automatic initialization has happened (when a secure connection is made),
+   * then a TlsException is thrown.
    *
    * The optional argument [database] is the path to a certificate database
    * directory containing root certificates for verifying certificate paths on
    * client connections, and server certificates to provide on server
-   * connections.  The argument [password] should be used when creating
+   * connections. The argument [password] should be used when creating
    * secure server sockets, to allow the private key of the server
-   * certificate to be fetched.  If [useBuiltinRoots] is true (the default),
+   * certificate to be fetched. If [useBuiltinRoots] is true (the default),
    * then a built-in set of root certificates for trusted certificate
    * authorities is merged with the certificates in the database.
    * The list of built-in root certificates, and documentation about this
@@ -161,7 +169,7 @@
    * http://www.mozilla.org/projects/security/certs/included/ .
    *
    * If the [database] argument is omitted, then only the
-   * builtin root certificates are used.  If [useBuiltinRoots] is also false,
+   * builtin root certificates are used. If [useBuiltinRoots] is also false,
    * then no certificates are available.
    *
    * Examples:
@@ -246,7 +254,19 @@
    * If the [socket] already has a subscription, pass the existing
    * subscription in the [subscription] parameter. The secure socket
    * will take over the subscription and process any subsequent
-   * events.
+   * events. In most cases calling `pause` on this subscription before
+   * starting TLS handshake is the right thing to do.
+   *
+   * If the [host] argument is passed it will be used as the host name
+   * for the TLS handshake. If [host] is not passed the host name from
+   * the [socket] will be used. The [host] can be either a [String] or
+   * an [InternetAddress].
+   *
+   * Calling this function will _not_ cause a DNS host lookup. If the
+   * [host] passed is a [String] the [InternetAddress] for the
+   * resulting [SecureSocket] will have this passed in [host] as its
+   * host value and the internet address of the already connected
+   * socket as its address value.
    *
    * See [connect] for more information on the arguments.
    *
@@ -340,10 +360,23 @@
 }
 
 
+class _FilterStatus {
+  bool progress = false;  // The filter read or wrote data to the buffers.
+  bool readEmpty = true;  // The read buffers and decryption filter are empty.
+  bool writeEmpty = true;  // The write buffers and encryption filter are empty.
+  // These are set if a buffer changes state from empty or full.
+  bool readPlaintextNoLongerEmpty = false;
+  bool writePlaintextNoLongerFull = false;
+  bool readEncryptedNoLongerFull = false;
+  bool writeEncryptedNoLongerEmpty = false;
+
+  _FilterStatus();
+}
+
+
 class _RawSecureSocket extends Stream<RawSocketEvent>
                        implements RawSecureSocket {
   // Status states
-  static final int NOT_CONNECTED = 200;
   static final int HANDSHAKE = 201;
   static final int CONNECTED = 202;
   static final int CLOSED = 203;
@@ -356,6 +389,9 @@
   static final int WRITE_ENCRYPTED = 3;
   static final int NUM_BUFFERS = 4;
 
+  // Is a buffer identifier for an encrypted buffer?
+  static bool _isBufferEncrypted(int identifier) => identifier >= READ_ENCRYPTED;
+
   RawSocket _socket;
   final Completer<_RawSecureSocket> _handshakeComplete =
       new Completer<_RawSecureSocket>();
@@ -372,17 +408,23 @@
   final bool sendClientCertificate;
   final Function onBadCertificate;
 
-  var _status = NOT_CONNECTED;
+  var _status = HANDSHAKE;
   bool _writeEventsEnabled = true;
   bool _readEventsEnabled = true;
+  int _pauseCount = 0;
+  bool _pendingReadEvent = false;
   bool _socketClosedRead = false;  // The network socket is closed for reading.
   bool _socketClosedWrite = false;  // The network socket is closed for writing.
   bool _closedRead = false;  // The secure socket has fired an onClosed event.
   bool _closedWrite = false;  // The secure socket has been closed for writing.
-  bool _filterReadEmpty = true;  // There is no buffered data to read.
-  bool _filterWriteEmpty = true;  // There is no buffered data to be written.
+  _FilterStatus _filterStatus = new _FilterStatus();
   bool _connectPending = false;
+  bool _filterPending = false;
+  bool _filterActive = false;
+
   _SecureFilter _secureFilter = new _SecureFilter();
+  int _filterPointer;
+  SendPort _filterService;
 
   static Future<_RawSecureSocket> connect(
       host,
@@ -397,8 +439,16 @@
        bool sendClientCertificate: false,
        bool onBadCertificate(X509Certificate certificate)}) {
     var future;
+    _verifyFields(host, requestedPort, certificateName, is_server,
+                 requestClientCertificate, requireClientCertificate,
+                 sendClientCertificate, onBadCertificate);
     if (host is String) {
-      future = InternetAddress.lookup(host).then((addrs) => addrs.first);
+      if (socket != null) {
+        future = new Future.value(
+            (socket.address as dynamic)._cloneWithNewHost(host));
+      } else {
+        future = InternetAddress.lookup(host).then((addrs) => addrs.first);
+      }
     } else {
       future = new Future.value(host);
     }
@@ -439,9 +489,8 @@
     _stream = _controller.stream;
     // Throw an ArgumentError if any field is invalid.  After this, all
     // errors will be reported through the future or the stream.
-    _verifyFields();
     _secureFilter.init();
-    if (_bufferedData != null) _readFromBuffered();
+    _filterPointer = _secureFilter._pointer();
     _secureFilter.registerHandshakeCompleteCallback(
         _secureHandshakeCompleteHandler);
     if (onBadCertificate != null) {
@@ -454,6 +503,7 @@
       futureSocket = new Future.value(socket);
     }
     futureSocket.then((rawSocket) {
+      _connectPending = true;
       _socket = rawSocket;
       _socket.readEventsEnabled = true;
       _socket.writeEventsEnabled = false;
@@ -461,15 +511,15 @@
         // If a current subscription is provided use this otherwise
         // create a new one.
         _socketSubscription = _socket.listen(_eventDispatcher,
-                                             onError: _errorHandler,
+                                             onError: _reportError,
                                              onDone: _doneHandler);
       } else {
         _socketSubscription.onData(_eventDispatcher);
-        _socketSubscription.onError(_errorHandler);
+        _socketSubscription.onError(_reportError);
         _socketSubscription.onDone(_doneHandler);
       }
-      _connectPending = true;
       _secureFilter.connect(address.host,
+                            (address as dynamic)._sockaddr_storage,
                             port,
                             is_server,
                             certificateName,
@@ -477,35 +527,38 @@
                                 requireClientCertificate,
                             requireClientCertificate,
                             sendClientCertificate);
-      _status = HANDSHAKE;
       _secureHandshake();
     })
-    .catchError((error) {
-      _handshakeComplete.completeError(error);
-      _close();
-    });
+    .catchError(_reportError);
   }
 
   StreamSubscription listen(void onData(RawSocketEvent data),
                             {void onError(error),
                              void onDone(),
                              bool cancelOnError}) {
-    if (_writeEventsEnabled) {
-      _writeEventsEnabled = false;
-      _controller.add(RawSocketEvent.WRITE);
-    }
+    _sendWriteEvent();
     return _stream.listen(onData,
                           onError: onError,
                           onDone: onDone,
                           cancelOnError: cancelOnError);
   }
 
-  void _verifyFields() {
-    assert(is_server is bool);
-    assert(_socket == null || _socket is RawSocket);
-    if (address is! InternetAddress) {
-      throw new ArgumentError(
-          "RawSecureSocket constructor: host is not an InternetAddress");
+  static void _verifyFields(host,
+                            int requestedPort,
+                            String certificateName,
+                            bool is_server,
+                            bool requestClientCertificate,
+                            bool requireClientCertificate,
+                            bool sendClientCertificate,
+                            Function onBadCertificate) {
+    if (host is! String && host is! InternetAddress) {
+      throw new ArgumentError("host is not a String or an InternetAddress");
+    }
+    if (requestedPort is! int) {
+      throw new ArgumentError("requestedPort is not an int");
+    }
+    if (requestedPort < 0 || requestedPort > 65535) {
+      throw new ArgumentError("requestedPort is not in the range 0..65535");
     }
     if (certificateName != null && certificateName is! String) {
       throw new ArgumentError("certificateName is not null or a String");
@@ -535,7 +588,6 @@
 
   int available() {
     if (_status != CONNECTED) return 0;
-    _readEncryptedData();
     return _secureFilter.buffers[READ_PLAINTEXT].length;
   }
 
@@ -551,7 +603,7 @@
     }
     _socketClosedWrite = true;
     _socketClosedRead = true;
-    if (_secureFilter != null) {
+    if (!_filterActive && _secureFilter != null) {
       _secureFilter.destroy();
       _secureFilter = null;
     }
@@ -566,8 +618,7 @@
     if (direction == SocketDirection.SEND ||
         direction == SocketDirection.BOTH) {
       _closedWrite = true;
-      _writeEncryptedData();
-      if (_filterWriteEmpty) {
+      if (_filterStatus.writeEmpty) {
         _socket.shutdown(SocketDirection.SEND);
         _socketClosedWrite = true;
         if (_closedRead) {
@@ -589,99 +640,60 @@
   bool get writeEventsEnabled => _writeEventsEnabled;
 
   void set writeEventsEnabled(bool value) {
-    if (value &&
-        _controller.hasListener &&
-        _secureFilter != null &&
-        _secureFilter.buffers[WRITE_PLAINTEXT].free > 0) {
-      Timer.run(() => _controller.add(RawSocketEvent.WRITE));
-    } else {
-      _writeEventsEnabled = value;
+    _writeEventsEnabled = value;
+    if (value) {
+      Timer.run(() => _sendWriteEvent());
     }
   }
 
   bool get readEventsEnabled => _readEventsEnabled;
 
   void set readEventsEnabled(bool value) {
-    _readEventsEnabled = value;
-    if (value &&
-        ((_secureFilter != null &&
-          _secureFilter.buffers[READ_PLAINTEXT].length > 0) ||
-         _socketClosedRead)) {
-      // We might not have no underlying socket to set off read events.
-      Timer.run(_readHandler);
-    }
+      _readEventsEnabled = value;
+      _scheduleReadEvent();
   }
 
-  List<int> read([int len]) {
+  List<int> read([int length]) {
+    if (length != null && (length is! int || length < 0)) {
+        throw new ArgumentError(
+            "Invalid length parameter in SecureSocket.read (length: $length)");
+    }
     if (_closedRead) {
       throw new SocketException("Reading from a closed socket");
     }
     if (_status != CONNECTED) {
       return null;
     }
-    var buffer = _secureFilter.buffers[READ_PLAINTEXT];
-    _readEncryptedData();
-    int toRead = buffer.length;
-    if (len != null) {
-      if (len is! int || len < 0) {
-        throw new ArgumentError(
-            "Invalid len parameter in SecureSocket.read (len: $len)");
-      }
-      if (len < toRead) {
-        toRead = len;
-      }
-    }
-    List<int> result = (toRead == 0) ? null :
-        buffer.data.sublist(buffer.start, buffer.start + toRead);
-    buffer.advanceStart(toRead);
-
-    // Set up a read event if the filter still has data.
-    if (!_filterReadEmpty) {
-      Timer.run(_readHandler);
-    }
-
-    if (_socketClosedRead) {  // An onClose event is pending.
-      // _closedRead is false, since we are in a read  call.
-      if (!_filterReadEmpty) {
-        // _filterReadEmpty may be out of date since read empties
-        // the plaintext buffer after calling _readEncryptedData.
-        // TODO(whesse): Fix this as part of fixing read.
-        _readEncryptedData();
-      }
-      if (_filterReadEmpty) {
-        // This can't be an else clause: the value of _filterReadEmpty changes.
-        // This must be asynchronous, because we are in a read call.
-        Timer.run(_closeHandler);
-      }
-    }
-
+    var result = _secureFilter.buffers[READ_PLAINTEXT].read(length);
+    _scheduleFilter();
     return result;
   }
 
-  // Write the data to the socket, and flush it as much as possible
-  // until it would block.  If the write would block, _writeEncryptedData sets
-  // up handlers to flush the pipeline when possible.
+  // Write the data to the socket, and schedule the filter to encrypt it.
   int write(List<int> data, [int offset, int bytes]) {
+    if (bytes != null && (bytes is! int || bytes < 0)) {
+        throw new ArgumentError(
+            "Invalid bytes parameter in SecureSocket.read (bytes: $bytes)");
+    }
+    if (offset != null && (offset is! int || offset < 0)) {
+        throw new ArgumentError(
+            "Invalid offset parameter in SecureSocket.read (offset: $offset)");
+    }
     if (_closedWrite) {
       _controller.addError(new SocketException("Writing to a closed socket"));
       return 0;
     }
     if (_status != CONNECTED) return 0;
-
     if (offset == null) offset = 0;
     if (bytes == null) bytes = data.length - offset;
 
-    var buffer = _secureFilter.buffers[WRITE_PLAINTEXT];
-    if (bytes > buffer.free) {
-      bytes = buffer.free;
+    int written =
+        _secureFilter.buffers[WRITE_PLAINTEXT].write(data, offset, bytes);
+    if (written > 0) {
+      _filterStatus.writeEmpty = false;
     }
-    if (bytes > 0) {
-      int startIndex = buffer.start + buffer.length;
-      buffer.data.setRange(startIndex, startIndex + bytes, data, offset);
-      buffer.length += bytes;
-    }
-    _writeEncryptedData();  // Tries to flush all pipeline stages.
-    return bytes;
+    _scheduleFilter();
+    return written;
   }
 
   X509Certificate get peerCertificate => _secureFilter.peerCertificate;
@@ -691,106 +703,43 @@
     return _socket.setOption(option, enabled);
   }
 
-  void _writeHandler() {
-    if (_status == CLOSED) return;
-    _writeEncryptedData();
-    if (_filterWriteEmpty && _closedWrite && !_socketClosedWrite) {
-      // Close _socket for write, by calling shutdown(), to avoid cloning the
-      // socket closing code in shutdown().
-      shutdown(SocketDirection.SEND);
-    }
-    if (_status == HANDSHAKE) {
-      try {
-        _secureHandshake();
-      } catch (e) { _reportError(e, "RawSecureSocket error"); }
-    } else if (_status == CONNECTED &&
-               _controller.hasListener &&
-               _writeEventsEnabled &&
-               _secureFilter.buffers[WRITE_PLAINTEXT].free > 0) {
-      // Reset the one-shot handler.
-      _writeEventsEnabled = false;
-      _controller.add(RawSocketEvent.WRITE);
-    }
-  }
-
   void _eventDispatcher(RawSocketEvent event) {
-    if (event == RawSocketEvent.READ) {
-      _readHandler();
-    } else if (event == RawSocketEvent.WRITE) {
-      _writeHandler();
-    } else if (event == RawSocketEvent.READ_CLOSED) {
-      _closeHandler();
-    }
-  }
-
-  void _readFromBuffered() {
-    assert(_bufferedData != null);
-    var encrypted = _secureFilter.buffers[READ_ENCRYPTED];
-    var bytes = _bufferedData.length - _bufferedDataIndex;
-    int startIndex = encrypted.start + encrypted.length;
-    encrypted.data.setRange(startIndex,
-                            startIndex + bytes,
-                            _bufferedData,
-                            _bufferedDataIndex);
-    encrypted.length += bytes;
-    _bufferedDataIndex += bytes;
-    if (_bufferedData.length == _bufferedDataIndex) {
-      _bufferedData = null;
+    try {
+      if (event == RawSocketEvent.READ) {
+        _readHandler();
+      } else if (event == RawSocketEvent.WRITE) {
+        _writeHandler();
+      } else if (event == RawSocketEvent.READ_CLOSED) {
+        _closeHandler();
+      }
+    } catch (e) {
+      _reportError(e);
     }
   }
 
   void _readHandler() {
-    if (_status == CLOSED) {
-      return;
-    } else if (_status == HANDSHAKE) {
-      try {
-        _secureHandshake();
-        if (_status != HANDSHAKE) _readHandler();
-      } catch (e) { _reportError(e, "RawSecureSocket error"); }
-    } else {
-      if (_status != CONNECTED) {
-        // Cannot happen.
-        throw new SocketException("Internal SocketIO Error");
-      }
-      try {
-        _readEncryptedData();
-      } catch (e) { _reportError(e, "RawSecureSocket error"); }
-      if (!_filterReadEmpty) {
-        if (_readEventsEnabled) {
-          if (_secureFilter.buffers[READ_PLAINTEXT].length > 0) {
-            _controller.add(RawSocketEvent.READ);
-          }
-          if (_socketClosedRead) {
-            // Keep firing read events until we are paused or buffer is empty.
-            Timer.run(_readHandler);
-          }
-        }
-      } else if (_socketClosedRead) {
-        _closeHandler();
-      }
-    }
+    _readSocket();
+    _scheduleFilter();
+  }
+
+  void _writeHandler() {
+    _writeSocket();
+    _scheduleFilter();
   }
 
   void _doneHandler() {
-    if (_filterReadEmpty) {
+    if (_filterStatus.readEmpty) {
       _close();
     }
   }
 
-  void _errorHandler(e) {
-    _reportError(e, 'Error on underlying RawSocket');
-  }
-
-  void _reportError(e, String message) {
-    // TODO(whesse): Call _reportError from all internal functions that throw.
-    if (e is SocketException) {
-      e = new SocketException('$message (${e.message})', e.osError);
-    } else if (e is OSError) {
-      e = new SocketException(message, e);
-    } else {
-      e = new SocketException('$message (${e.toString()})', null);
-    }
+  void _reportError(e) {
     if (_connectPending) {
+      // _connectPending is true after the underlying connection has been
+      // made, but before the handshake has completed.
+      if (e is! TlsException) {
+        e = new HandshakeException("$e", null);
+      }
       _handshakeComplete.completeError(e);
     } else {
       _controller.addError(e);
@@ -802,38 +751,58 @@
     if  (_status == CONNECTED) {
       if (_closedRead) return;
       _socketClosedRead = true;
-      if (_filterReadEmpty) {
+      if (_filterStatus.readEmpty) {
         _closedRead = true;
         _controller.add(RawSocketEvent.READ_CLOSED);
         if (_socketClosedWrite) {
           _close();
         }
+      } else {
+        _scheduleFilter();
       }
     } else if (_status == HANDSHAKE) {
+      _socketClosedRead = true;
+      if (_filterStatus.readEmpty) {
       _reportError(
-          new SocketException('Connection terminated during handshake'),
-          'handshake error');
+          new HandshakeException('Connection terminated during handshake'));
+      } else {
+        _secureHandshake();
+      }
     }
   }
 
   void _secureHandshake() {
-    _readEncryptedData();
-    _secureFilter.handshake();
-    _writeEncryptedData();
+    try {
+      _secureFilter.handshake();
+      _filterStatus.writeEmpty = false;
+      _readSocket();
+      _writeSocket();
+      _scheduleFilter();
+    } catch (e) {
+      _reportError(e);
+    }
   }
 
   void _secureHandshakeCompleteHandler() {
     _status = CONNECTED;
     if (_connectPending) {
       _connectPending = false;
-      // If we complete the future synchronously, user code will run here,
-      // and modify the state of the RawSecureSocket.  For example, it
-      // could close the socket, and set _filter to null.
+      // We don't want user code to run synchronously in this callback.
       Timer.run(() => _handshakeComplete.complete(this));
     }
   }
 
   void _onPauseStateChange() {
+    if (_controller.isPaused) {
+      _pauseCount++;
+    } else {
+      _pauseCount--;
+      if (_pauseCount == 0) {
+        _scheduleReadEvent();
+        _sendWriteEvent();  // Can send event synchronously.
+      }
+    }
+
     if (!_socketClosedRead || !_socketClosedWrite) {
       if (_controller.isPaused) {
         _socketSubscription.pause();
@@ -849,121 +818,333 @@
     }
   }
 
-  void _readEncryptedData() {
-    // Read from the socket, and push it through the filter as far as
-    // possible.
-    var encrypted = _secureFilter.buffers[READ_ENCRYPTED];
-    var plaintext = _secureFilter.buffers[READ_PLAINTEXT];
-    bool progress = true;
-    while (progress) {
-      progress = false;
-      // Do not try to read plaintext from the filter while handshaking.
-      if ((_status == CONNECTED) && plaintext.free > 0) {
-        int bytes = _secureFilter.processBuffer(READ_PLAINTEXT);
-        if (bytes > 0) {
-          plaintext.length += bytes;
-          progress = true;
-        }
-      }
-      if (encrypted.length > 0) {
-        int bytes = _secureFilter.processBuffer(READ_ENCRYPTED);
-        if (bytes > 0) {
-          encrypted.advanceStart(bytes);
-          progress = true;
-        }
-      }
-      if (!_socketClosedRead && encrypted.free > 0) {
-        if (_bufferedData != null) {
-          _readFromBuffered();
-          progress = true;
-        } else {
-          List<int> data = _socket.read(encrypted.free);
-          if (data != null) {
-            int bytes = data.length;
-            int startIndex = encrypted.start + encrypted.length;
-            encrypted.data.setRange(startIndex, startIndex + bytes, data);
-            encrypted.length += bytes;
-            progress = true;
-          }
-        }
-      }
-    }
-    // If there is any data in any stages of the filter, there should
-    // be data in the plaintext buffer after this process.
-    // TODO(whesse): Verify that this is true, and there can be no
-    // partial encrypted block stuck in the secureFilter.
-    _filterReadEmpty = (plaintext.length == 0);
+  void _scheduleFilter() {
+    _filterPending = true;
+    _tryFilter();
   }
 
-  void _writeEncryptedData() {
-    if (_socketClosedWrite) return;
-    var encrypted = _secureFilter.buffers[WRITE_ENCRYPTED];
-    var plaintext = _secureFilter.buffers[WRITE_PLAINTEXT];
-    while (true) {
-      if (encrypted.length > 0) {
-        // Write from the filter to the socket.
-        int bytes = _socket.write(encrypted.data,
-                                  encrypted.start,
-                                  encrypted.length);
-        encrypted.advanceStart(bytes);
-        if (encrypted.length > 0) {
-          // The socket has blocked while we have data to write.
-          // We must be notified when it becomes unblocked.
-          _socket.writeEventsEnabled = true;
-          _filterWriteEmpty = false;
-          break;
+  void _tryFilter() {
+    if (_status == CLOSED) return;
+    if (_filterPending && !_filterActive) {
+      _filterActive = true;
+      _filterPending = false;
+      _pushAllFilterStages().then((status) {
+        _filterStatus = status;
+        _filterActive = false;
+        if (_status == CLOSED) {
+          _secureFilter.destroy();
+          _secureFilter = null;
+          return;
         }
-      } else {
-        var plaintext = _secureFilter.buffers[WRITE_PLAINTEXT];
-        if (plaintext.length > 0) {
-           int plaintext_bytes = _secureFilter.processBuffer(WRITE_PLAINTEXT);
-           plaintext.advanceStart(plaintext_bytes);
+        if (_filterStatus.writeEmpty && _closedWrite && !_socketClosedWrite) {
+          // Checks for and handles all cases of partially closed sockets.
+          shutdown(SocketDirection.SEND);
+          if (_status == CLOSED) return;
         }
-        int bytes = _secureFilter.processBuffer(WRITE_ENCRYPTED);
-        if (bytes <= 0) {
-          // We know the WRITE_ENCRYPTED buffer is empty, and the
-          // filter wrote zero bytes to it, so the filter must be empty.
-          // Also, the WRITE_PLAINTEXT buffer must have been empty, or
-          // it would have written to the filter.
-          // TODO(whesse): Verify that the filter works this way.
-          _filterWriteEmpty = true;
-          break;
+        if (_filterStatus.readEmpty && _socketClosedRead && !_closedRead) {
+          if (_status == HANDSHAKE) {
+            _secureFilter.handshake();
+            if (_status == HANDSHAKE) {
+              throw new HandshakeException(
+                  'Connection terminated during handshake');
+            }
+          }
+          _closeHandler();
         }
-        encrypted.length += bytes;
-      }
+        if (_status == CLOSED) return;
+        if (_filterStatus.progress) {
+          _filterPending = true;
+          if (_filterStatus.writePlaintextNoLongerFull) _sendWriteEvent();
+          if (_filterStatus.readEncryptedNoLongerFull) _readSocket();
+          if (_filterStatus.writeEncryptedNoLongerEmpty) _writeSocket();
+          if (_filterStatus.readPlaintextNoLongerEmpty) _scheduleReadEvent();
+          if (_status == HANDSHAKE) _secureHandshake();
+        }
+        _tryFilter();
+      }).catchError(_reportError);
     }
   }
+
+  List<int> _readSocketOrBufferedData(int bytes) {
+    if (_bufferedData != null) {
+      if (bytes > _bufferedData.length - _bufferedDataIndex) {
+        bytes = _bufferedData.length - _bufferedDataIndex;
+      }
+      var result = _bufferedData.sublist(_bufferedDataIndex,
+                                          _bufferedDataIndex + bytes);
+      _bufferedDataIndex += bytes;
+      if (_bufferedData.length == _bufferedDataIndex) {
+        _bufferedData = null;
+      }
+      return result;
+    } else if (!_socketClosedRead) {
+      return _socket.read(bytes);
+    } else {
+      return null;
+    }
+  }
+
+  void _readSocket() {
+    if (_status == CLOSED) return;
+    var buffer = _secureFilter.buffers[READ_ENCRYPTED];
+    if (buffer.writeFromSource(_readSocketOrBufferedData) > 0) {
+      _filterStatus.readEmpty = false;
+    }
+  }
+
+  void _writeSocket() {
+    if (_socketClosedWrite) return;
+    var buffer = _secureFilter.buffers[WRITE_ENCRYPTED];
+    if (buffer.readToSocket(_socket)) {  // Returns true if blocked
+      _socket.writeEventsEnabled = true;
+    }
+  }
+
+  // If a read event should be sent, add it to the controller.
+  _scheduleReadEvent() {
+    if (!_pendingReadEvent &&
+        _readEventsEnabled &&
+        _pauseCount == 0 &&
+        _secureFilter != null &&
+        !_secureFilter.buffers[READ_PLAINTEXT].isEmpty) {
+      _pendingReadEvent = true;
+      Timer.run(_sendReadEvent);
+    }
+  }
+
+  _sendReadEvent() {
+    _pendingReadEvent = false;
+    if (_readEventsEnabled &&
+        _pauseCount == 0 &&
+        _secureFilter != null &&
+        !_secureFilter.buffers[READ_PLAINTEXT].isEmpty) {
+      _controller.add(RawSocketEvent.READ);
+      _scheduleReadEvent();
+    }
+  }
+
+  // If a write event should be sent, add it to the controller.
+  _sendWriteEvent() {
+    if (!_closedWrite &&
+        _writeEventsEnabled &&
+        _pauseCount == 0 &&
+        _secureFilter != null &&
+        _secureFilter.buffers[WRITE_PLAINTEXT].free > 0) {
+      _writeEventsEnabled = false;
+      _controller.add(RawSocketEvent.WRITE);
+    }
+  }
+
+  Future<_FilterStatus> _pushAllFilterStages() {
+    if (_filterService == null) {
+      _filterService = _SecureFilter._newServicePort();
+    }
+    List args = [_filterPointer, _status != CONNECTED];
+    var bufs = _secureFilter.buffers;
+    for (var i = 0; i < NUM_BUFFERS; ++i) {
+      args.add(bufs[i].start);
+      args.add(bufs[i].end);
+    }
+
+    return _filterService.call(args).then((response) {
+      bool wasInHandshake = response[1];
+      int start(int index) => response[2 * index + 2];
+      int end(int index) => response[2 * index + 3];
+
+      _FilterStatus status = new _FilterStatus();
+      // Compute writeEmpty as "write plaintext buffer and write encrypted
+      // buffer were empty when we started and are empty now".
+      status.writeEmpty = bufs[WRITE_PLAINTEXT].isEmpty &&
+          start(WRITE_ENCRYPTED) == end(WRITE_ENCRYPTED);
+      // If we were in handshake when this started, _writeEmpty may be false
+      // because the handshake wrote data after we checked.
+      if (wasInHandshake) status.writeEmpty = false;
+
+      // Compute readEmpty as "both read buffers were empty when we started
+      // and are empty now".
+      status.readEmpty = bufs[READ_ENCRYPTED].isEmpty &&
+          start(READ_PLAINTEXT) == end(READ_PLAINTEXT);
+
+      _ExternalBuffer buffer = bufs[WRITE_PLAINTEXT];
+      int new_start = start(WRITE_PLAINTEXT);
+      if (new_start != buffer.start) {
+        status.progress = true;
+        if (buffer.free == 0) {
+          status.writePlaintextNoLongerFull = true;
+        }
+        buffer.start = new_start;
+      }
+      buffer = bufs[READ_ENCRYPTED];
+      new_start = start(READ_ENCRYPTED);
+      if (new_start != buffer.start) {
+        status.progress = true;
+        if (buffer.free == 0) {
+          status.readEncryptedNoLongerFull = true;
+        }
+        buffer.start = new_start;
+      }
+      buffer = bufs[WRITE_ENCRYPTED];
+      int new_end = end(WRITE_ENCRYPTED);
+      if (new_end != buffer.end) {
+        status.progress = true;
+        if (buffer.length == 0) {
+          status.writeEncryptedNoLongerEmpty = true;
+        }
+        buffer.end = new_end;
+      }
+      buffer = bufs[READ_PLAINTEXT];
+      new_end = end(READ_PLAINTEXT);
+      if (new_end != buffer.end) {
+        status.progress = true;
+        if (buffer.length == 0) {
+          status.readPlaintextNoLongerEmpty = true;
+        }
+        buffer.end = new_end;
+      }
+      return status;
+    });
+  }
 }
 
 
+/**
+ * A circular buffer backed by an external byte array.  Accessed from
+ * both C++ and Dart code in an unsynchronized way, with one reading
+ * and one writing.  All updates to start and end are done by Dart code.
+ */
 class _ExternalBuffer {
-  // Performance is improved if a full buffer of plaintext fits
-  // in the encrypted buffer, when encrypted.
-  static final int SIZE = 8 * 1024;
-  static final int ENCRYPTED_SIZE = 10 * 1024;
-  _ExternalBuffer() : start = 0, length = 0;
+  _ExternalBuffer(this.size) {
+    start = size~/2;
+    end = size~/2;
+  }
 
-  // TODO(whesse): Consider making this a circular buffer.  Only if it helps.
-  void advanceStart(int numBytes) {
-    start += numBytes;
-    length -= numBytes;
-    if (length == 0) {
-      start = 0;
+  void advanceStart(int bytes) {
+    assert(start > end || start + bytes <= end);
+    start += bytes;
+    if (start >= size) {
+      start -= size;
+      assert(start <= end);
+      assert(start < size);
     }
   }
 
-  int get free => data.length - (start + length);
+  void advanceEnd(int bytes) {
+    assert(start <= end || start > end + bytes);
+    end += bytes;
+    if (end >= size) {
+      end -= size;
+      assert(end < start);
+      assert(end < size);
+    }
+  }
+
+  bool get isEmpty => end == start;
+
+  int get length {
+    if (start > end) return size + end - start;
+    return end - start;
+  }
+
+  int get linearLength {
+    if (start > end) return size - start;
+    return end - start;
+  }
+
+  int get free {
+    if (start > end) return start - end - 1;
+    return size + start - end - 1;
+  }
+
+  int get linearFree {
+    if (start > end) return start - end - 1;
+    if (start == 0) return size - end - 1;
+    return size - end;
+  }
+
+  List<int> read(int bytes) {
+    if (bytes == null) {
+      bytes = length;
+    } else {
+      bytes = min(bytes, length);
+    }
+    if (bytes == 0) return null;
+    List<int> result = new Uint8List(bytes);
+    int bytesRead = 0;
+    // Loop over zero, one, or two linear data ranges.
+    while (bytesRead < bytes) {
+      int toRead = linearLength;
+      result.setRange(bytesRead,
+                      bytesRead + toRead,
+                      data,
+                      start);
+      advanceStart(toRead);
+      bytesRead += toRead;
+    }
+    return result;
+  }
+
+  int write(List<int> inputData, int offset, int bytes) {
+    if (bytes > free) {
+      bytes = free;
+    }
+    int written = 0;
+    int toWrite = min(bytes, linearFree);
+    // Loop over zero, one, or two linear data ranges.
+    while (toWrite > 0) {
+      data.setRange(end, end + toWrite, inputData, offset);
+      advanceEnd(toWrite);
+      offset += toWrite;
+      written += toWrite;
+      toWrite = min(bytes - written, linearFree);
+    }
+    return written;
+  }
+
+  int writeFromSource(List<int> getData(int requested)) {
+    int written = 0;
+    int toWrite = linearFree;
+    // Loop over zero, one, or two linear data ranges.
+    while (toWrite > 0) {
+      // Source returns at most toWrite bytes, and it returns null when empty.
+      var inputData = getData(toWrite);
+      if (inputData == null) break;
+      var len = inputData.length;
+      data.setRange(end, end + len, inputData);
+      advanceEnd(len);
+      written += len;
+      toWrite = linearFree;
+    }
+    return written;
+  }
+
+  bool readToSocket(RawSocket socket) {
+    // Loop over zero, one, or two linear data ranges.
+    while (true) {
+      var toWrite = linearLength;
+      if (toWrite == 0) return false;
+      int bytes = socket.write(data, start, toWrite);
+      advanceStart(bytes);
+      if (bytes < toWrite) {
+        // The socket has blocked while we have data to write.
+        return true;
+      }
+    }
+  }
 
   List data;  // This will be a ExternalByteArray, backed by C allocated data.
   int start;
-  int length;
+  int end;
+  final size;
 }
 
 
 abstract class _SecureFilter {
   external factory _SecureFilter();
 
+  external static SendPort _newServicePort();
+
   void connect(String hostName,
+               Uint8List addr,
                int port,
                bool is_server,
                String certificateName,
@@ -977,6 +1158,61 @@
   int processBuffer(int bufferIndex);
   void registerBadCertificateCallback(Function callback);
   void registerHandshakeCompleteCallback(Function handshakeCompleteHandler);
+  int _pointer();
 
   List<_ExternalBuffer> get buffers;
 }
+
+/** A secure networking exception caused by a failure in the
+ *  TLS/SSL protocol.
+ */
+class TlsException implements IOException {
+  final String type;
+  final String message;
+  final OSError osError;
+
+  const TlsException([String message = "",
+                      OSError osError = null])
+     : this._("TlsException", message, osError);
+
+  const TlsException._(String this.type,
+                       String this.message,
+                       OSError this.osError);
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write(type);
+    if (!message.isEmpty) {
+      sb.write(": $message");
+      if (osError != null) {
+        sb.write(" ($osError)");
+      }
+    } else if (osError != null) {
+      sb.write(": $osError");
+    }
+    return sb.toString();
+  }
+}
+
+
+/**
+ * An exception that happens in the handshake phase of establishing
+ * a secure network connection.
+ */
+class HandshakeException extends TlsException {
+  const HandshakeException([String message = "",
+                            OSError osError = null])
+     : super._("HandshakeException", message, osError);
+}
+
+
+/**
+ * An exception that happens in the handshake phase of establishing
+ * a secure network connection, when looking up or verifying a
+ * certificate.
+ */
+class CertificateException extends TlsException {
+  const CertificateException([String message = "",
+                            OSError osError = null])
+     : super._("CertificateException", message, osError);
+}
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index 7164bf1..a74f2a1 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -87,6 +87,22 @@
   String get host;
 
   /**
+   * Returns true if the [InternetAddress] is a loopback address.
+   */
+  bool get isLoopback;
+
+  /**
+   * Returns true if the [InternetAddress]s scope is a link-local.
+   */
+  bool get isLinkLocal;
+
+  /**
+   * Perform a reverse dns lookup on the [address], creating a new
+   * [InternetAddress] where the host field set to the result.
+   */
+  Future<InternetAddress> reverse();
+
+  /**
    * Lookup a host, returning a Future of a list of
    * [InternetAddress]s. If [type] is [InternetAddressType.ANY], it
    * will lookup both IP version 4 (IPv4) and IP version 6 (IPv6)
@@ -99,6 +115,44 @@
       String host, {InternetAddressType type: InternetAddressType.ANY});
 }
 
+
+/**
+ * A [NetworkInterface] represent an active network interface on the current
+ * system. It contains a list of [InternetAddress]s, that's bound to the
+ * interface.
+ */
+abstract class NetworkInterface {
+  /**
+   * Get the name of the [NetworkInterface].
+   */
+  String get name;
+
+  /**
+   * Get a list of [InternetAddress]s currently bound to this
+   * [NetworkInterface].
+   */
+  List<InternetAddress> get addresses;
+
+  /**
+   * Query the system for [NetworkInterface]s.
+   *
+   * If [includeLoopback] is `true`, the returned list will include the
+   * loopback device. Default is `false`.
+   *
+   * If [includeLinkLocal] is `true`, the list of addresses of the returned
+   * [NetworkInterface]s, may include link local addresses. Default is `false`.
+   *
+   * If [type] is either [InternetAddressType.IP_V4] or
+   * [InternetAddressType.IP_V6] it will only lookup addresses of the
+   * specified type. Default is [InternetAddressType.ANY].
+   */
+  external static Future<List<NetworkInterface>> list({
+      bool includeLoopback: false,
+      bool includeLinkLocal: false,
+      InternetAddressType type: InternetAddressType.ANY});
+}
+
+
 /**
  * A [RawServerSocket] represents a listening socket, and provides a
  * stream of low-level [RawSocket] objects, one for each connection
diff --git a/sdk/lib/io/string_transformer.dart b/sdk/lib/io/string_transformer.dart
index f127b38..e08e807 100644
--- a/sdk/lib/io/string_transformer.dart
+++ b/sdk/lib/io/string_transformer.dart
@@ -91,8 +91,34 @@
   var _decoder;
 
   /**
+   * Decodes a stream of bytes into a `String` with an optional
+   * [encoding] and [replacementChar].
+   *
+   * The default value for [encoding] is [Encoding.UTF_8].
+   *
+   * The default value for [replacementChar] is code point U+FFFD.
+   *
+   * Completes with the decoded `String` when the stream is done.
+   */
+  static Future<String> decode(
+      Stream<List<int>> stream,
+      [Encoding encoding = Encoding.UTF_8,
+       int replacementChar = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+    return stream
+        .transform(new StringDecoder(encoding, replacementChar))
+        .fold(
+            new StringBuffer(),
+            (prev, data) => prev..write(data))
+        .then((sb) => sb.toString());
+  }
+
+  /**
    * Create a new [StringDecoder] with an optional [encoding] and
    * [replacementChar].
+   *
+   * The default value for [encoding] is [Encoding.UTF_8].
+   *
+   * The default value for [replacementChar] is code point U+FFFD.
    */
   StringDecoder([Encoding encoding = Encoding.UTF_8, int replacementChar]) {
     switch (encoding) {
diff --git a/sdk/lib/mdv_observe_impl/mdv_observe_impl.dart b/sdk/lib/mdv_observe_impl/mdv_observe_impl.dart
index e83a15d..9429da1 100644
--- a/sdk/lib/mdv_observe_impl/mdv_observe_impl.dart
+++ b/sdk/lib/mdv_observe_impl/mdv_observe_impl.dart
@@ -12,6 +12,8 @@
 import 'dart:async';
 import 'dart:collection';
 
+part 'path_observer.dart';
+
 /**
  * Interface representing an observable object. This is used by data in
  * model-view architectures to notify interested parties of [changes].
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index f6ba0c9..e29c225 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -665,7 +665,7 @@
    * An immutable map from names to mirrors for all constructor
    * declarations for this type.
    */
-   Map<Symbol, MethodMirror> get constructors;
+  Map<Symbol, MethodMirror> get constructors;
 
   /**
    * An immutable map from names to mirrors for all type variables for
@@ -673,7 +673,7 @@
    *
    * This map preserves the order of declaration of the type variables.
    */
-   Map<Symbol, TypeVariableMirror> get typeVariables;
+  Map<Symbol, TypeVariableMirror> get typeVariables;
 
   /**
    * An immutable map from names to mirrors for all type arguments for
diff --git a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
index 1fcecdb..41e2450 100644
--- a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
+++ b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
@@ -318,11 +318,11 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  num firstWhere(bool test(num value), { num orElse() }) {
+  dynamic firstWhere(bool test(num value), { Object orElse() }) {
     return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  num lastWhere(bool test(num value), {num orElse()}) {
+  dynamic lastWhere(bool test(num value), { Object orElse() }) {
     return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
@@ -540,11 +540,11 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  num firstWhere(bool test(num value), { num orElse() }) {
+  dynamic firstWhere(bool test(num value), { Object orElse() }) {
     return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  num lastWhere(bool test(num value), {num orElse()}) {
+  dynamic lastWhere(bool test(num value), { Object orElse() }) {
     return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
@@ -762,11 +762,11 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstWhere(bool test(int value), { int orElse() }) {
+  dynamic firstWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastWhere(bool test(int value), {int orElse()}) {
+  dynamic lastWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
@@ -984,11 +984,11 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstWhere(bool test(int value), { int orElse() }) {
+  dynamic firstWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastWhere(bool test(int value), {int orElse()}) {
+  dynamic lastWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
@@ -1206,11 +1206,11 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstWhere(bool test(int value), { int orElse() }) {
+  dynamic firstWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastWhere(bool test(int value), {int orElse()}) {
+  dynamic lastWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
@@ -1428,11 +1428,11 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstWhere(bool test(int value), { int orElse() }) {
+  dynamic firstWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastWhere(bool test(int value), {int orElse()}) {
+  dynamic lastWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
@@ -1650,11 +1650,11 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstWhere(bool test(int value), { int orElse() }) {
+  dynamic firstWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastWhere(bool test(int value), {int orElse()}) {
+  dynamic lastWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
@@ -1871,11 +1871,11 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstWhere(bool test(int value), { int orElse() }) {
+  dynamic firstWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastWhere(bool test(int value), {int orElse()}) {
+  dynamic lastWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
@@ -2093,11 +2093,11 @@
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  int firstWhere(bool test(int value), { int orElse() }) {
+  dynamic firstWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  int lastWhere(bool test(int value), {int orElse()}) {
+  dynamic lastWhere(bool test(int value), { Object orElse() }) {
     return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
diff --git a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
index 1cad109..eb14d3a 100644
--- a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
+++ b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
@@ -7,7 +7,7 @@
 import 'dart:typed_data';
 import 'dart:_js_helper' show Creates, JSName, Null, Returns, convertDartClosureToJS;
 import 'dart:_foreign_helper' show JS;
-import 'dart:_interceptors' show Interceptor;
+import 'dart:_interceptors' show Interceptor, JSExtendableArray;
 // DO NOT EDIT - unless you are editing documentation as per:
 // https://code.google.com/p/dart/wiki/ContributingHTMLDocumentation
 // Auto-generated dart:web_gl library.
@@ -669,6 +669,11 @@
   @DomName('EXTDrawBuffers.MAX_DRAW_BUFFERS_EXT')
   @DocsEditable
   static const int MAX_DRAW_BUFFERS_EXT = 0x8824;
+
+  @JSName('drawBuffersEXT')
+  @DomName('EXTDrawBuffers.drawBuffersEXT')
+  @DocsEditable
+  void drawBuffersExt(List<int> buffers) 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
@@ -2320,8 +2325,8 @@
 
   @DomName('WebGLRenderingContext.getParameter')
   @DocsEditable
-  @Creates('Null|num|String|bool|=List|Float32List|Int32List|Uint32List|Framebuffer|Renderbuffer|Texture')
-  @Returns('Null|num|String|bool|=List|Float32List|Int32List|Uint32List|Framebuffer|Renderbuffer|Texture')
+  @Creates('Null|num|String|bool|JSExtendableArray|Float32List|Int32List|Uint32List|Framebuffer|Renderbuffer|Texture')
+  @Returns('Null|num|String|bool|JSExtendableArray|Float32List|Int32List|Uint32List|Framebuffer|Renderbuffer|Texture')
   Object getParameter(int pname) native;
 
   @DomName('WebGLRenderingContext.getProgramInfoLog')
@@ -2370,8 +2375,8 @@
 
   @DomName('WebGLRenderingContext.getUniform')
   @DocsEditable
-  @Creates('Null|num|String|bool|=List|Float32List|Int32List|Uint32List')
-  @Returns('Null|num|String|bool|=List|Float32List|Int32List|Uint32List')
+  @Creates('Null|num|String|bool|JSExtendableArray|Float32List|Int32List|Uint32List')
+  @Returns('Null|num|String|bool|JSExtendableArray|Float32List|Int32List|Uint32List')
   Object getUniform(Program program, UniformLocation location) native;
 
   @DomName('WebGLRenderingContext.getUniformLocation')
diff --git a/sdk/lib/web_gl/dartium/web_gl_dartium.dart b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
index a1e5550..9506607 100644
--- a/sdk/lib/web_gl/dartium/web_gl_dartium.dart
+++ b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
@@ -735,6 +735,10 @@
   @DocsEditable
   static const int MAX_DRAW_BUFFERS_EXT = 0x8824;
 
+  @DomName('EXTDrawBuffers.drawBuffersEXT')
+  @DocsEditable
+  void drawBuffersExt(List<int> buffers) native "EXTDrawBuffers_drawBuffersEXT_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
diff --git a/tests/async_helper.dart b/tests/async_helper.dart
new file mode 100644
index 0000000..34d471e
--- /dev/null
+++ b/tests/async_helper.dart
@@ -0,0 +1,54 @@
+// 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.
+
+/// This library is used for testing asynchronous tests.
+/// If a test is asynchronous, it needs to notify the testing driver
+/// about this (otherwise tests may get reported as passing [after main()
+/// finished] even if the asynchronous operations fail).
+/// Tests which can't use the unittest framework should use the helper functions
+/// in this library.
+/// This library provides two methods
+///  - asyncStart(): Needs to be called before an asynchronous operation is
+///                  scheduled.
+///  - asyncEnd(): Needs to be called as soon as the asynchronous operation
+///                ended.
+/// After the last asyncStart() called was matched with a corresponding
+/// asyncEnd() call, the testing driver will be notified that the tests is done.
+
+library async_helper;
+
+
+bool _initialized = false;
+int _asyncLevel = 0;
+
+Exception _buildException(String msg) {
+  return new Exception('Fatal: $msg. This is most likely a bug in your test.');
+}
+
+void asyncStart() {
+  if (_initialized && _asyncLevel == 0) {
+    throw _buildException('asyncStart() was called even though we are done '
+                          'with testing.');
+  }
+  if (!_initialized) {
+    print('unittest-suite-wait-for-done');
+    _initialized = true;
+  }
+  _asyncLevel++;
+}
+
+void asyncEnd() {
+  if (_asyncLevel <= 0) {
+    if (!_initialized) {
+      throw _buildException('asyncEnd() was called before asyncStart().');
+    } else {
+      throw _buildException('asyncEnd() was called more often than '
+                            'asyncStart().');
+    }
+  }
+  _asyncLevel--;
+  if (_asyncLevel == 0) {
+    print('unittest-suite-done');
+  }
+}
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
index c3a7852..98b0881 100644
--- a/tests/co19/co19-analyzer.status
+++ b/tests/co19/co19-analyzer.status
@@ -4,154 +4,71 @@
 
 [ $compiler == dartanalyzer ]
 Language/05_Variables/05_Variables_A05_t04: fail
-Language/06_Functions/06_Functions_A01_t31: fail
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t06: fail
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t07: fail
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: fail
-Language/06_Functions/2_Formal_Parameters_A01_t02: fail
-Language/06_Functions/2_Formal_Parameters_A01_t09: fail
 Language/06_Functions/2_Formal_Parameters_A02_t02: fail
-Language/07_Classes/07_Classes_A01_t20: fail
-Language/07_Classes/07_Classes_A09_t01: fail
-Language/07_Classes/07_Classes_A09_t02: fail
-Language/07_Classes/07_Classes_A09_t03: fail
-Language/07_Classes/07_Classes_A09_t04: fail
-Language/07_Classes/2_Getters_A04_t03: fail
-Language/07_Classes/2_Getters_A04_t04: fail
-Language/07_Classes/2_Getters_A04_t05: fail
-Language/07_Classes/2_Getters_A04_t07: fail
-Language/07_Classes/3_Setters_A03_t02: fail
-Language/07_Classes/3_Setters_A03_t04: fail
-Language/07_Classes/3_Setters_A03_t06: fail
-Language/07_Classes/3_Setters_A03_t08: fail
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: fail
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: fail
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A11_t09: fail
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A14_t01: fail
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A14_t04: fail
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A15_t07: fail
-Language/07_Classes/6_Constructors/2_Factories_A06_t01: fail
-Language/07_Classes/6_Constructors/2_Factories_A06_t02: fail
-Language/07_Classes/6_Constructors/2_Factories_A06_t04: fail
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t01: fail
 Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t02: fail
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t03: fail
-Language/07_Classes/7_Static_Methods_A01_t01: fail
-Language/09_Generics/09_Generics_A04_t07: fail
-Language/11_Expressions/01_Constants_A01_t01: fail
-Language/11_Expressions/01_Constants_A11_t03: fail
-Language/11_Expressions/01_Constants_A15_t07: fail
-Language/11_Expressions/01_Constants_A15_t08: fail
 Language/11_Expressions/01_Constants_A16_t01: fail
 Language/11_Expressions/01_Constants_A16_t02: fail
 Language/11_Expressions/01_Constants_A16_t03: fail
 Language/11_Expressions/01_Constants_A17_t03: fail
-Language/11_Expressions/01_Constants_A19_t04: fail
-Language/11_Expressions/03_Numbers_A01_t01: fail
-Language/11_Expressions/03_Numbers_A01_t02: fail
-Language/11_Expressions/03_Numbers_A01_t03: fail
-Language/11_Expressions/03_Numbers_A01_t04: fail
-Language/11_Expressions/03_Numbers_A01_t08: fail
-Language/11_Expressions/03_Numbers_A01_t10: fail
-Language/11_Expressions/05_Strings/1_String_Interpolation_A03_t01: fail
-Language/11_Expressions/05_Strings/1_String_Interpolation_A04_t01: fail
 Language/11_Expressions/05_Strings_A02_t46: fail
 Language/11_Expressions/05_Strings_A02_t48: fail
-Language/11_Expressions/06_Lists_A03_t01: fail
-Language/11_Expressions/06_Lists_A06_t01: fail
 Language/11_Expressions/11_Instance_Creation/1_New_A13_t02: fail
-Language/11_Expressions/11_Instance_Creation/2_Const_A06_t01: fail
-Language/11_Expressions/11_Instance_Creation/2_Const_A10_t01: fail
 Language/11_Expressions/11_Instance_Creation_A05_t02: fail
-Language/11_Expressions/14_Function_Invocation/1_Actual_Argument_List_Evaluation_A02_t01: fail
-Language/11_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t05: fail
-Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A02_t01: fail
-Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A05_t01: fail
-Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A04_t01: fail
-Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A08_t01: fail
-Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t01: fail
-Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t07: fail
-Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t05: fail
-Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A06_t02: fail
-Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: fail
-Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A03_t01: fail
-Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A03_t02: fail
-Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A03_t03: fail
-Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A03_t04: fail
-Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A08_t02: fail
 Language/11_Expressions/22_Equality_A01_t15: fail
 Language/11_Expressions/22_Equality_A01_t16: fail
-Language/11_Expressions/28_Postfix_Expressions_A01_t06: fail
-Language/11_Expressions/30_Identifier_Reference_A01_t07: fail
-Language/11_Expressions/30_Identifier_Reference_A01_t08: fail
-Language/11_Expressions/33_Argument_Definition_Test_A01_t14: fail
-Language/11_Expressions/33_Argument_Definition_Test_A01_t18: fail
-Language/12_Statements/02_Expression_Statements_A01_t06: fail
-Language/12_Statements/09_Switch_A04_t01: fail
-Language/13_Libraries_and_Scripts/13_Libraries_and_Scripts_A03_t17: fail
-Language/13_Libraries_and_Scripts/1_Imports_A01_t46: fail
-Language/13_Libraries_and_Scripts/1_Imports_A04_t03: fail
 Language/13_Libraries_and_Scripts/1_Imports_A05_t01: fail
-Language/13_Libraries_and_Scripts/2_Exports_A05_t01: fail
 Language/13_Libraries_and_Scripts/5_URIs_A01_t24: fail
 Language/13_Libraries_and_Scripts/5_URIs_A01_t25: fail
 Language/14_Types/3_Type_Declarations/1_Typedef_A07_t01: fail
 Language/14_Types/3_Type_Declarations/1_Typedef_A07_t02: fail
 Language/14_Types/3_Type_Declarations/1_Typedef_A07_t03: fail
 Language/14_Types/3_Type_Declarations/1_Typedef_A07_t04: fail
-Language/14_Types/4_Interface_Types_A10_t03: fail
-Language/14_Types/4_Interface_Types_A10_t04: fail
-Language/14_Types/4_Interface_Types_A10_t09: fail
 Language/15_Reference/1_Lexical_Rules/1_Reserved_Words_A40_t04: fail
-Language/15_Reference/1_Lexical_Rules_A01_t10: fail
 Language/15_Reference/1_Lexical_Rules_A02_t06: fail
-LibTest/core/AssertionError/column_A01_t02: fail
-LibTest/core/AssertionError/failedAssertion_A01_t01: fail
-LibTest/core/AssertionError/line_A01_t02: fail
-LibTest/core/AssertionError/url_A01_t01: fail
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A03_t02: fail
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A04_t01: fail
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: fail
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: fail
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: fail
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A07_t01: fail
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A08_t01: fail
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A08_t02: fail
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A09_t01: fail
-LibTest/core/Set/isSubsetOf_A01_t01: fail
-LibTest/core/Set/isSubsetOf_A01_t02: fail
-LibTest/core/String/String_class_A01_t01: fail
-LibTest/core/String/charCodeAt_A01_t01: fail
-LibTest/core/String/charCodeAt_A02_t01: fail
-LibTest/core/String/charCodeAt_A03_t01: fail
-LibTest/core/String/charCodes_A01_t01: fail
-LibTest/core/String/concat_A01_t01: fail
-LibTest/core/String/concat_A02_t01: fail
-LibTest/core/String/hashCode_A01_t01: fail
-LibTest/core/String/splitChars_A01_t01: fail
-LibTest/core/StringBuffer/addAll_A01_t01: fail
-LibTest/core/StringBuffer/addAll_A01_t02: fail
-LibTest/core/StringBuffer/addAll_A03_t01: fail
-LibTest/core/StringBuffer/add_A01_t01: fail
-LibTest/core/StringBuffer/add_A01_t02: fail
-LibTest/core/StringBuffer/isEmpty_A01_t01: fail
-LibTest/core/StringBuffer/toString_A01_t01: fail
-LibTest/core/double/ceil_A01_t05: fail
-LibTest/core/double/floor_A01_t05: fail
-LibTest/core/int/operator_division_A01_t01: fail
+
 
 # fails locally, passes on bot
 Language/13_Libraries_and_Scripts/3_Parts_A02_t03: skip
 
+# co19 issue #380, Strings class has been removed
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: fail, OK
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: fail, OK
+
+# co19 issue #382, Deprecated parts of String interface is being removed.
+LibTest/core/String/charCodes_A01_t01: fail, OK
+LibTest/core/String/charCodeAt_A02_t01: fail, OK
+LibTest/core/String/charCodeAt_A03_t01: fail, OK
+LibTest/core/String/charCodeAt_A01_t01: fail, OK
+LibTest/core/String/splitChars_A01_t01: fail, OK
+
+# co19 issue #389, ceil, floor, truncate and round return integers
+LibTest/core/int/operator_division_A01_t01: fail
+
+# co19 issue #395, uses dart:io API (outdated)
+Language/15_Reference/1_Lexical_Rules_A01_t10: Fail, OK
+
 # co19 issue #397, List.addLast removed
+Language/11_Expressions/06_Lists_A06_t01: fail, OK
 LibTest/core/Iterable/where_A01_t07: fail, OK
 LibTest/core/List/addLast_A01_t01: fail, OK
 LibTest/core/List/addLast_A01_t03: fail, OK
 LibTest/core/List/addLast_A02_t01: fail, OK
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: fail, OK
 
 # co19 issue #400, collection library reorg
 LibTest/core/List/List.fixedLength_A01_t01: fail, OK
 LibTest/core/List/operator_subscript_A01_t02: fail, OK
+LibTest/core/String/String_class_A01_t01: fail, OK
+LibTest/core/String/concat_A01_t01: fail, OK
+LibTest/core/String/concat_A02_t01: fail, OK
+LibTest/core/String/hashCode_A01_t01: fail, OK
+LibTest/core/Set/isSubsetOf_A01_t01: fail, OK
+LibTest/core/Set/isSubsetOf_A01_t02: fail, OK
 
 # co19 issue #403
 LibTest/core/List/List_A01_t02: fail, OK
@@ -210,3 +127,70 @@
 Language/05_Variables/05_Variables_A12_t06: fail, OK
 Language/05_Variables/05_Variables_A13_t01: fail, OK
 Language/07_Classes/07_Classes_A02_t11: fail, OK
+
+# co19 issue #429, It is a compile-time error if a formal parameter is declared as a constant variable
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A15_t07: fail, OK
+
+# co19 issue #430, return not subtype from factory
+Language/07_Classes/6_Constructors/2_Factories_A06_t01: fail, OK
+Language/07_Classes/6_Constructors/2_Factories_A06_t02: fail, OK
+Language/07_Classes/6_Constructors/2_Factories_A06_t04: fail, OK
+
+# co19 issue #431, it is OK to use 'double' argument for const constructor
+Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t01: fail, OK
+Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t03: fail, OK
+
+# co19 issue #428, number literals with a + prefix
+Language/11_Expressions/01_Constants_A01_t01: fail, OK
+Language/11_Expressions/03_Numbers_A01_t01: fail, OK
+Language/11_Expressions/03_Numbers_A01_t02: fail, OK
+Language/11_Expressions/03_Numbers_A01_t03: fail, OK
+Language/11_Expressions/03_Numbers_A01_t04: fail, OK
+Language/11_Expressions/03_Numbers_A01_t08: fail, OK
+Language/11_Expressions/03_Numbers_A01_t10: fail, OK
+Language/12_Statements/02_Expression_Statements_A01_t06: fail, OK
+LibTest/core/double/ceil_A01_t05: fail, OK
+LibTest/core/double/floor_A01_t05: fail, OK
+
+# co19 issue #385, library name is not required
+Language/13_Libraries_and_Scripts/1_Imports_A04_t03: fail, OK
+Language/13_Libraries_and_Scripts/2_Exports_A05_t01: fail, OK
+
+# co19 issue #388, StringBuffer renamed add to write
+Language/11_Expressions/05_Strings/1_String_Interpolation_A03_t01: fail, OK
+Language/11_Expressions/05_Strings/1_String_Interpolation_A04_t01: fail, OK
+Language/11_Expressions/14_Function_Invocation/1_Actual_Argument_List_Evaluation_A02_t01: fail, OK
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A04_t01: fail, OK
+Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t05: fail, OK
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: fail, OK
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A03_t02: fail, OK
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A04_t01: fail, OK
+LibTest/core/StringBuffer/addAll_A03_t01: fail, OK
+LibTest/core/StringBuffer/add_A01_t01: fail, OK
+LibTest/core/StringBuffer/add_A01_t02: fail, OK
+LibTest/core/StringBuffer/addAll_A01_t01: fail, OK
+LibTest/core/StringBuffer/addAll_A01_t02: fail, OK
+LibTest/core/StringBuffer/isEmpty_A01_t01: fail, OK
+LibTest/core/StringBuffer/toString_A01_t01: fail, OK
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A07_t01: fail, OK
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A08_t01: fail, OK
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A08_t02: fail, OK
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A09_t01: fail, OK
+
+#co19 issue #432, missing @static-warning annotation
+Language/14_Types/8_Parameterized_Types_A03_t03: fail,OK
+Language/14_Types/8_Parameterized_Types_A03_t05: fail,OK
+
+# co19 issue #433, missing @static-warning annotation
+Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t01: fail, OK
+Language/11_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t07: fail, OK
+
+# co19 issue #434, argument definition was dropped
+Language/11_Expressions/33_Argument_Definition_Test_A01_t14: fail, OK
+Language/11_Expressions/33_Argument_Definition_Test_A01_t18: fail, OK
+
+# co19 issue #435, AssertioError has not properties
+LibTest/core/AssertionError/column_A01_t02: fail, OK
+LibTest/core/AssertionError/failedAssertion_A01_t01: fail, OK
+LibTest/core/AssertionError/line_A01_t02: fail, OK
+LibTest/core/AssertionError/url_A01_t01: fail, OK
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 065b1c1..dcbf037 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -19,7 +19,6 @@
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: Fail # TODO(dart2dart-team): Please triage this failure.
 Language/07_Classes/9_Superclasses/1_Inheritance_and_Overriding_A01_t03: Fail # TODO(dart2dart-team): Please triage this failure.
 Language/11_Expressions/01_Constants_A18_t06: Fail # TODO(dart2dart-team): Please triage this failure.
-Language/11_Expressions/11_Instance_Creation/2_Const_A03_t01: Fail # TODO(dart2dart-team): Please triage this failure.
 Language/11_Expressions/11_Instance_Creation_A05_t02: Fail # TODO(dart2dart-team): Please triage this failure.
 Language/11_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t10: Fail # TODO(dart2dart-team): Please triage this failure.
 Language/11_Expressions/33_Argument_Definition_Test_A02_t02: Fail # TODO(dart2dart-team): Please triage this failure.
@@ -253,7 +252,6 @@
 Language/11_Expressions/05_Strings_A20_t01: Fail # inherited from VM
 Language/11_Expressions/06_Lists_A03_t01: Fail # http://dartbug.com/5519
 Language/11_Expressions/06_Lists_A03_t02: Fail # http://dartbug.com/5519
-Language/11_Expressions/06_Lists_A04_t01: Fail # http://dartbug.com/5519
 Language/11_Expressions/07_Maps_A01_t01: Skip # co19 issue 91: map literals illegal at statement beginning.
 Language/11_Expressions/07_Maps_A02_t01: Fail # http://dartbug.com/5519
 Language/11_Expressions/07_Maps_A02_t02: Fail # http://dartbug.com/5519
@@ -421,6 +419,17 @@
 LibTest/core/String/lastIndexOf_A01_t02: Fail # Issue 427
 
 [ $compiler == dart2dart && $minified ]
+Language/14_Types/5_Function_Types_A01_t07: Fail # dartbug.com/11467
+Language/14_Types/5_Function_Types_A01_t08: Fail # dartbug.com/11467
+Language/14_Types/5_Function_Types_A01_t09: Fail # dartbug.com/11467
+Language/14_Types/5_Function_Types_A01_t11: Fail # dartbug.com/11467
+Language/14_Types/5_Function_Types_A02_t05: Fail # dartbug.com/11467
+Language/14_Types/5_Function_Types_A02_t09: Fail # dartbug.com/11467
+Language/14_Types/5_Function_Types_A02_t10: Fail # dartbug.com/11467
+Language/14_Types/5_Function_Types_A03_t06: Fail # dartbug.com/11467
+Language/14_Types/5_Function_Types_A03_t10: Fail # dartbug.com/11467
+Language/14_Types/5_Function_Types_A03_t11: Fail # dartbug.com/11467
+
 Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: Fail, OK # co19 issue 396
 Language/11_Expressions/17_Getter_Invocation_A02_t01: Fail, OK # co19 issue 396
 Language/11_Expressions/18_Assignment_A05_t02: Fail, OK # co19 issue 396
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index fb5aa0d..28e9415 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -4,6 +4,7 @@
 
 [ $compiler == dart2js && $runtime == jsshell ]
 LibTest/isolate/isolate_api/spawnUri_A02_t01: Crash # TODO(ahe): Please triage this crash.
+LibTest/core/List/sort_A01_t04: Pass, Timeout # Must be a bug in jsshell, test sometimes times out.
 
 [ $compiler == dart2js && $checked && $runtime == ie9 ]
 LibTest/core/Map/Map_class_A01_t04: Slow, Pass
@@ -47,7 +48,6 @@
 Language/11_Expressions/11_Instance_Creation/1_New_A02_t06: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/11_Instance_Creation/1_New_A02_t07: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/11_Instance_Creation/2_Const_A01_t02: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/11_Instance_Creation/2_Const_A03_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/11_Instance_Creation/2_Const_A11_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/11_Instance_Creation/2_Const_A11_t03: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/11_Instance_Creation_A05_t02: Fail # TODO(ahe): Please triage this failure.
@@ -77,7 +77,6 @@
 Language/12_Statements/04_Local_Function_Declaration_A02_t02: Fail # TODO(ahe): Please triage this failure.
 Language/12_Statements/09_Switch_A02_t02: Fail # TODO(ahe): Please triage this failure.
 Language/12_Statements/09_Switch_A06_t02: Fail # co19 issue 413
-Language/12_Statements/10_Try_A06_t01: Fail # TODO(ahe): Please triage this failure.
 Language/12_Statements/10_Try_A07_t03: Fail # TODO(ahe): Please triage this failure.
 Language/12_Statements/11_Return_A05_t01: Fail # TODO(ahe): Please triage this failure.
 Language/12_Statements/11_Return_A05_t02: Fail # TODO(ahe): Please triage this failure.
@@ -170,8 +169,6 @@
 [ $compiler == dart2js && $runtime == ie9 ]
 Language/11_Expressions/03_Numbers_A01_t06: Fail # Issue: 8920
 Language/11_Expressions/03_Numbers_A01_t09: Fail # Issue: 8920
-Language/11_Expressions/06_Lists_A07_t02: Fail # Issue: 8920
-Language/11_Expressions/07_Maps_A06_t02: Fail # Issue: 8920
 Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: Fail # Issue: 8920
 LibTest/core/Date/Date_A01_t03: Fail # Issue: 8920
 LibTest/core/Date/Date.fromString_A03_t01: Fail # Issue: 8920
@@ -225,6 +222,8 @@
 Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail, OK
 Language/11_Expressions/18_Assignment_A08_t04: Fail, OK
 
+[ $compiler == dart2js && ($minified || $runtime == ie9) ]
+Language/12_Statements/10_Try_A06_t01: Fail # BUG(11480): Triage.
 
 [ $compiler == dart2js && $checked ]
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A17_t03: Fail # TODO(ahe): Please triage this failure.
@@ -234,7 +233,6 @@
 Language/11_Expressions/03_Numbers_A05_t02: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/06_Lists_A09_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/06_Lists_A09_t04: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/06_Lists_A09_t05: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/07_Maps_A10_t05: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/07_Maps_A11_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/11_Instance_Creation/1_New_A07_t01: Fail # TODO(ahe): Please triage this failure.
@@ -269,8 +267,6 @@
 
 Language/11_Expressions/11_Instance_Creation/1_New_A12_t02: Fail # http://dartbug.com/3970
 
-Language/14_Types/3_Type_Declarations/1_Typedef_A01_t01: Fail # http://dartbug.com/5022
-
 
 Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: Fail, OK # co19 issue 405
 Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail, OK # co19 issue 405
@@ -618,7 +614,13 @@
 Language/11_Expressions/30_Identifier_Reference_A02_t01: Fail # Pseudo keyword "abstract".
 
 Language/12_Statements/06_For_A01_t11: Fail # http://dartbug.com/9824
-Language/14_Types/6_Type_dynamic_A03_t01: Fail # Renamed Date to DateTime (issue 373, 374)
+
+
+# BUG(11331): Renamed Date to DateTime (issue 373, 374) but this only has an
+# impact on V8, because of the way method calls are evaluated. Needs more
+# investigation.
+[ $compiler == dart2js && $runtime == d8 ]
+Language/14_Types/6_Type_dynamic_A03_t01: Fail
 
 
 [ $compiler == dart2js && $jscl ]
@@ -628,10 +630,6 @@
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Expect.fail('Some exception expected')
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Expect.fail('Some exception expected')
 
-Language/11_Expressions/06_Lists_A07_t02: Fail # generic type information is lost during canonicalization.
-Language/11_Expressions/07_Maps_A06_t02: Fail # generic type information is lost during canonicalization.
-
-
 
 #
 # The following tests may be broken, but require further review.
@@ -692,7 +690,6 @@
 Language/11_Expressions/01_Constants_A16_t02: Fail # Checks that an OutOfMemoryException raised during evaluation of a compile-time constant causes a compile-time error.
 Language/11_Expressions/05_Strings_A02_t46: Fail # Checks that multi-line strings that contain characters and sequences prohibited by this grammar, cause compile-time errors.
 Language/11_Expressions/05_Strings_A02_t48: Fail # Checks that multi-line strings that contain characters and sequences prohibited by this grammar, cause compile-time errors.
-Language/11_Expressions/06_Lists_A04_t01: Fail # Checks that it is a compile-time error if the type argument of a constant list literal includes a type variable.
 Language/11_Expressions/22_Equality_A01_t15: Fail # Checks that equality expressions cannot be operands of another equality expression.
 Language/11_Expressions/22_Equality_A01_t16: Fail # Checks that equality expressions cannot be operands of another equality expression.
 Language/11_Expressions/23_Relational_Expressions_A01_t10: Fail # Checks that a relational expression cannot be the operand of another relational expression.
@@ -716,7 +713,6 @@
 Language/07_Classes/3_Setters_A04_t06: Fail # http://dartbug.com/5023
 Language/07_Classes/3_Setters_A04_t07: Fail # http://dartbug.com/5023
 
-
 Language/13_Libraries_and_Scripts/4_Scripts_A03_t01: Fail # http://dartbug.com/5683
 Language/13_Libraries_and_Scripts/4_Scripts_A03_t03: Fail # http://dartbug.com/5683
 
@@ -727,6 +723,9 @@
 # Unexpected runtime errors.
 #
 [ $compiler == dart2js ]
+#Language/11_Expressions/32_Type_Cast_A01_t01: Fail # http://dartbug.com/9074
+
+#Language/14_Types/4_Interface_Types_A08_t06: Fail # class Queue cannot be resolved.
 
 Language/14_Types/4_Interface_Types_A11_t04: Fail # http://dartbug.com/5020
 Language/14_Types/4_Interface_Types_A12_t10: Fail # http://dartbug.com/5020
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 6a518b5..82e9361 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -2,6 +2,9 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+[ $runtime == vm && $system == windows ]
+LibTest/core/Stopwatch/elapsed_A01_t01: Pass, Fail # Issue 11382.
+
 [ $runtime == vm ]
 Language/11_Expressions/33_Argument_Definition_Test_A02_t02: Crash, Pass # http://dartbug.com/9597
 Language/07_Classes/6_Constructors_A02_t01: Skip # co19 issue 415.
@@ -508,7 +511,6 @@
 LibTest/math/sin_A01_t01: Pass, Fail
 LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
 LibTest/core/int/operator_unary_minus_A01_t01: Pass, Fail
-LibTest/math/Random/nextDouble_A01_t01: Pass, Fail
 
 
 [ $compiler == none && $runtime == vm && $arch == arm && $mode == debug ]
@@ -519,28 +521,39 @@
 LibTest/core/double/floor_A01_t02: Fail
 LibTest/core/double/truncate_A01_t01: Fail
 
-
-[ $compiler == none && $runtime == vm && $arch == simarm ]
-LibTest/math/tan_A01_t01: Pass, Fail
-LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
-LibTest/core/int/operator_unary_minus_A01_t01: Fail, Pass # Pass on Mac
+[ $compiler == none && $runtime == vm && $arch == simarm && $mode == release ]
+LibTest/math/tan_A01_t01: Fail
 LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
-LibTest/math/Random/nextDouble_A01_t01: Pass, Crash
-
+LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
+LibTest/core/int/operator_unary_minus_A01_t01: Fail
+LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
 
 [ $compiler == none && $runtime == vm && $arch == simarm && $mode == debug ]
-LibTest/core/Expect/throws_A01_t04: Crash
+LibTest/math/tan_A01_t01: Fail
+LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
 LibTest/core/List/sort_A01_t05: Crash
 LibTest/core/List/sort_A01_t06: Crash
-LibTest/core/double/ceil_A01_t02: Fail, Pass # Pass on Mac
-LibTest/core/double/floor_A01_t02: Fail, Pass # Pass on Mac
-LibTest/core/double/truncate_A01_t01: Fail, Pass # Pass on Mac
-
+LibTest/core/double/ceil_A01_t02: Fail, Pass # Passes on Mac.
+LibTest/core/double/floor_A01_t02: Fail, Pass # Passes on Mac.
+LibTest/core/double/truncate_A01_t01: Fail, Pass # Passes on Mac.
+LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
+LibTest/core/int/operator_unary_minus_A01_t01: Fail
 
 [ $compiler == none && $runtime == vm && $arch == mips ]
 *: Skip
 
 
-[ $compiler == none && $runtime == vm && $arch == simmips ]
-*: Skip
+[ $compiler == none && $runtime == vm && $arch == simmips && $mode == release ]
+LibTest/math/tan_A01_t01: Fail
+LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
+LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
+LibTest/core/int/operator_unary_minus_A01_t01: Fail
 
+[ $compiler == none && $runtime == vm && $arch == simmips && $mode == debug ]
+LibTest/math/tan_A01_t01: Fail
+LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
+LibTest/core/List/sort_A01_t04: Crash # Too far relative jump.
+LibTest/core/List/sort_A01_t05: Crash
+LibTest/core/List/sort_A01_t06: Crash
+LibTest/core/int/operator_unary_minus_A01_t01: Fail
+LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
diff --git a/tests/compiler/dart2js/analyze_api_test.dart b/tests/compiler/dart2js/analyze_api_test.dart
index 29ad0ef..5c6da03 100644
--- a/tests/compiler/dart2js/analyze_api_test.dart
+++ b/tests/compiler/dart2js/analyze_api_test.dart
@@ -20,7 +20,7 @@
 // TODO(johnniwinther): Support canonical URIs as keys and message kinds as
 // values.
 const Map<String, List<String>> WHITE_LIST = const {
-  'html_dart2js.dart':
+  'path_observer.dart':
       const ['Warning: Using "new Symbol"', // Issue 10565.
             ],
 };
diff --git a/tests/compiler/dart2js/bad_loop_test.dart b/tests/compiler/dart2js/bad_loop_test.dart
index dbf8795..5cecb22 100644
--- a/tests/compiler/dart2js/bad_loop_test.dart
+++ b/tests/compiler/dart2js/bad_loop_test.dart
@@ -9,7 +9,7 @@
        show Diagnostic;
 
 main() {
-  Uri script = currentDirectory.resolve(nativeToUriPath(new Options().script));
+  Uri script = currentDirectory.resolve(nativeToUriPath(Platform.script));
   Uri libraryRoot = script.resolve('../../../sdk/');
   Uri packageRoot = script.resolve('./packages/');
 
diff --git a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
index d3fd545..0e7b685 100644
--- a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
+++ b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
@@ -222,7 +222,7 @@
       int index = 0;
       signature.forEachParameter((Element element) {
         Expect.equals(expectedTypes[index++],
-            inferrer.internal.typeOf[element].simplify(inferrer.compiler));
+            inferrer.getTypeOfElement(element).simplify(inferrer.compiler));
       });
       Expect.equals(index, expectedTypes.length);
   });
@@ -247,14 +247,12 @@
   runTest(TEST_7a, (inferrer) => [subclassOfInterceptor(inferrer)]);
   runTest(TEST_7b, (inferrer) => [inferrer.dynamicType.nonNullable()]);
 
-  // In the following tests, we can't infer the right types because we
-  // have recursive calls with the same parameters. We should build a
-  // constraint system for those, to find the types.
-  runTest(TEST_8, (inferrer) => [inferrer.dynamicType,
+  runTest(TEST_8, (inferrer) => [inferrer.intType,
                                  subclassOfInterceptor(inferrer),
                                  inferrer.dynamicType.nonNullable()]);
-  runTest(TEST_9, (inferrer) => [inferrer.dynamicType, inferrer.dynamicType]);
-  runTest(TEST_10, (inferrer) => [inferrer.dynamicType, inferrer.dynamicType]);
+  runTest(TEST_9, (inferrer) => [inferrer.intType, inferrer.intType]);
+  runTest(TEST_10, (inferrer) => [subclassOfInterceptor(inferrer),
+                                  subclassOfInterceptor(inferrer)]);
   runTest(TEST_11, (inferrer) => [subclassOfInterceptor(inferrer),
                                   subclassOfInterceptor(inferrer)]);
 
@@ -274,7 +272,8 @@
                                   inferrer.boolType,
                                   inferrer.doubleType]);
 
-  runTest(TEST_18, (inferrer) => [inferrer.dynamicType, inferrer.dynamicType]);
+  runTest(TEST_18, (inferrer) => [subclassOfInterceptor(inferrer),
+                                  subclassOfInterceptor(inferrer)]);
 }
 
 void main() {
diff --git a/tests/compiler/dart2js/codegen_helper.dart b/tests/compiler/dart2js/codegen_helper.dart
index 23884da..4e8d498 100644
--- a/tests/compiler/dart2js/codegen_helper.dart
+++ b/tests/compiler/dart2js/codegen_helper.dart
@@ -9,7 +9,7 @@
     show SourceString;
 
 Map<String, String> generate(String code, [List<String> options = const []]) {
-  Uri script = currentDirectory.resolve(nativeToUriPath(new Options().script));
+  Uri script = currentDirectory.resolve(nativeToUriPath(Platform.script));
   Uri libraryRoot = script.resolve('../../../sdk/');
   Uri packageRoot = script.resolve('./packages/');
 
diff --git a/tests/compiler/dart2js/concrete_type_inference_test.dart b/tests/compiler/dart2js/concrete_type_inference_test.dart
index 8284448..71d8488 100644
--- a/tests/compiler/dart2js/concrete_type_inference_test.dart
+++ b/tests/compiler/dart2js/concrete_type_inference_test.dart
@@ -34,7 +34,7 @@
           printElement.computeSignature(compiler).requiredParameters.head;
         var type = compiler.typesTask.getGuaranteedTypeOfElement(parameter);
         var inferrer = compiler.typesTask.typesInferrer;
-        Expect.identical(inferrer.dynamicType, type);
+        Expect.identical(inferrer.dynamicType, type.simplify(compiler));
       });
 
   compileAndFind(
@@ -63,7 +63,7 @@
   });
   checkPrintType('[]', (compiler, type) {
     var inferrer = compiler.typesTask.typesInferrer;
-    if (type.isContainer) type = type.asFlat;
+    if (type.isForwarding) type = type.forwardTo;
     Expect.identical(inferrer.growableListType, type);
   });
   checkPrintType('null', (compiler, type) {
diff --git a/tests/compiler/dart2js/cpa_inference_test.dart b/tests/compiler/dart2js/cpa_inference_test.dart
index 493a8b7..0040e8c 100644
--- a/tests/compiler/dart2js/cpa_inference_test.dart
+++ b/tests/compiler/dart2js/cpa_inference_test.dart
@@ -159,7 +159,9 @@
   class Object {}
   class Function {}
   abstract class List<E> {
-    factory List([int length]) => JS('=List', r'new Array(#)', length);
+    factory List([int length]) {
+      return JS('JSExtendableArray', r'new Array(#)', length);
+    }
   }
   abstract class Map<K, V> {}
   class Closure {}
@@ -1123,6 +1125,7 @@
 testJsCall() {
   final String source = r"""
     import 'dart:foreign';
+    import 'dart:interceptors';
 
     class A {}
     class B extends A {}
@@ -1138,7 +1141,7 @@
 
       var a = JS('', '1');
       var b = JS('Object', '1');
-      var c = JS('=List', '1');
+      var c = JS('JSExtendableArray', '1');
       var d = JS('String', '1');
       var e = JS('int', '1');
       var f = JS('double', '1');
@@ -1152,7 +1155,8 @@
   AnalysisResult result = analyze(source);
   result.checkNodeHasUnknownType('a');
   result.checkNodeHasUnknownType('b');
-  result.checkNodeHasType('c', [result.nullType, result.list]);
+  // TODO(polux): Fix this test.
+  // result.checkNodeHasType('c', [result.nullType, result.list]);
   result.checkNodeHasType('d', [result.nullType, result.string]);
   result.checkNodeHasType('e', [result.nullType, result.int]);
   result.checkNodeHasType('f', [result.nullType, result.double]);
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
index eec688a..b6b1065 100644
--- a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
@@ -13,7 +13,7 @@
        as dart2js;
 
 void main() {
-  Uri script = currentDirectory.resolve(nativeToUriPath(new Options().script));
+  Uri script = currentDirectory.resolve(nativeToUriPath(Platform.script));
   Uri libraryRoot = script.resolve('../../../sdk/');
   Uri packageRoot = script.resolve('./packages/');
 
diff --git a/tests/compiler/dart2js/diagnose_ambiguous_test.dart b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
index cd10b1b..39f9d8f 100644
--- a/tests/compiler/dart2js/diagnose_ambiguous_test.dart
+++ b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
@@ -11,7 +11,7 @@
 import 'dart:json';
 
 main() {
-  Uri script = currentDirectory.resolve(nativeToUriPath(new Options().script));
+  Uri script = currentDirectory.resolve(nativeToUriPath(Platform.script));
   Uri libraryRoot = script.resolve('../../../sdk/');
   Uri packageRoot = script.resolve('./packages/');
 
diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
index 1e25741..db2d968 100644
--- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -453,7 +453,7 @@
       (inferrer, field) {
         TypeMask type = f(inferrer);
         TypeMask inferredType =
-            inferrer.internal.typeOf[field].simplify(inferrer.compiler);
+            inferrer.getTypeOfElement(field).simplify(inferrer.compiler);
         Expect.equals(type, inferredType, name);
     });
   });
@@ -522,8 +522,8 @@
                     'f3': (inferrer) => inferrer.intType.nullable(),
                     'f4': (inferrer) => inferrer.intType.nullable()});
 
-  runTest(TEST_24, {'f1': (inferrer) => inferrer.numType,
-                    'f2': (inferrer) => inferrer.numType,
+  runTest(TEST_24, {'f1': (inferrer) => inferrer.intType,
+                    'f2': (inferrer) => inferrer.intType,
                     'f3': (inferrer) => inferrer.intType,
                     'f4': (inferrer) => inferrer.intType,
                     'f5': (inferrer) => inferrer.numType.nullable(),
diff --git a/tests/compiler/dart2js/inferrer_factory_test.dart b/tests/compiler/dart2js/inferrer_factory_test.dart
new file mode 100644
index 0000000..7e2c9ec
--- /dev/null
+++ b/tests/compiler/dart2js/inferrer_factory_test.dart
@@ -0,0 +1,30 @@
+// 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:expect/expect.dart";
+import 'compiler_helper.dart';
+
+const String TEST1 = r"""
+class A implements List {
+  factory A() {
+    // Avoid inlining by using try/catch.
+    try {
+      return new List();
+    } catch (e) {
+    }
+  }
+}
+
+main() {
+  new A()[0] = 42;
+}
+""";
+
+main() {
+  String generated = compileAll(TEST1);
+  // Check that we're using the index operator on the object returned
+  // by the A factory.
+  Expect.isTrue(generated.contains('[0] = 42'));
+}
+
diff --git a/tests/compiler/dart2js/list_tracer_node_type_test.dart b/tests/compiler/dart2js/list_tracer_node_type_test.dart
index e8022e6..ad06034 100644
--- a/tests/compiler/dart2js/list_tracer_node_type_test.dart
+++ b/tests/compiler/dart2js/list_tracer_node_type_test.dart
@@ -29,6 +29,14 @@
 }
 """;
 
+const String TEST4 = r"""
+main() {
+  var a = new List.filled(42, null);
+  a[0] = 42;
+  return a[0] + 42;
+}
+""";
+
 
 main() {
   String generated = compileAll(TEST1);
@@ -45,4 +53,8 @@
   generated = compileAll(TEST3);
   Expect.isFalse(generated.contains('if (typeof t1'));
   Expect.isTrue(generated.contains('if (t1 == null)'));
+
+  generated = compileAll(TEST4);
+  Expect.isFalse(generated.contains('if (typeof t1'));
+  Expect.isTrue(generated.contains('if (t1 == null)'));
 }
diff --git a/tests/compiler/dart2js/list_tracer_test.dart b/tests/compiler/dart2js/list_tracer_test.dart
index a82cac8..d782239 100644
--- a/tests/compiler/dart2js/list_tracer_test.dart
+++ b/tests/compiler/dart2js/list_tracer_test.dart
@@ -85,6 +85,7 @@
 var listPassedAsOptionalParameter = $listAllocation;
 var listPassedAsNamedParameter = $listAllocation;
 var listSetInNonFinalField = $listAllocation;
+var listWithChangedLength = $listAllocation;
 
 foo(list) {
   list[0] = aDouble;
@@ -170,17 +171,22 @@
 
   listSetInNonFinalField[0] = anInt;
   new B(listSetInNonFinalField);
+
+  listWithChangedLength[0] = anInt;
+  listWithChangedLength.length = 54;
 }
 """;
 }
 
 void main() {
-  doTest('[]'); // Test literal list.
-  doTest('new List()'); // Test growable list.
-  doTest('new List(1)'); // Test fixed list.
+  doTest('[]', nullify: false); // Test literal list.
+  doTest('new List()', nullify: false); // Test growable list.
+  doTest('new List(1)', nullify: true); // Test fixed list.
+  doTest('new List.filled(1, 0)', nullify: false); // Test List.filled.
+  doTest('new List.filled(1, null)', nullify: true); // Test List.filled.
 }
 
-void doTest(String allocation) {
+void doTest(String allocation, {bool nullify}) {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(generateTest(allocation), uri);
   compiler.runCompiler(uri);
@@ -188,26 +194,28 @@
 
   checkType(String name, type) {
     var element = findElement(compiler, name);
-    ContainerTypeMask mask = typesInferrer.internal.typeOf[element];
+    ContainerTypeMask mask = typesInferrer.getTypeOfElement(element);
+    if (nullify) type = type.nullable();
     Expect.equals(type, mask.elementType.simplify(compiler), name);
   }
 
-  checkType('listInField', typesInferrer.numType.nullable());
-  checkType('listPassedToMethod', typesInferrer.numType.nullable());
-  checkType('listReturnedFromMethod', typesInferrer.numType.nullable());
-  checkType('listUsedWithCascade', typesInferrer.numType.nullable());
-  checkType('listUsedInClosure', typesInferrer.numType.nullable());
-  checkType('listPassedToSelector', typesInferrer.numType.nullable());
-  checkType('listReturnedFromSelector', typesInferrer.numType.nullable());
-  checkType('listUsedWithAddAndInsert', typesInferrer.numType.nullable());
-  checkType('listUsedWithConstraint', typesInferrer.numType.nullable());
-  checkType('listEscapingFromSetter', typesInferrer.numType.nullable());
-  checkType('listUsedInLocal', typesInferrer.numType.nullable());
-  checkType('listEscapingInSetterValue', typesInferrer.numType.nullable());
-  checkType('listEscapingInIndex', typesInferrer.numType.nullable());
-  checkType('listEscapingInIndexSet', typesInferrer.intType.nullable());
-  checkType('listEscapingTwiceInIndexSet', typesInferrer.numType.nullable());
-  checkType('listSetInNonFinalField', typesInferrer.numType.nullable());
+  checkType('listInField', typesInferrer.numType);
+  checkType('listPassedToMethod', typesInferrer.numType);
+  checkType('listReturnedFromMethod', typesInferrer.numType);
+  checkType('listUsedWithCascade', typesInferrer.numType);
+  checkType('listUsedInClosure', typesInferrer.numType);
+  checkType('listPassedToSelector', typesInferrer.numType);
+  checkType('listReturnedFromSelector', typesInferrer.numType);
+  checkType('listUsedWithAddAndInsert', typesInferrer.numType);
+  checkType('listUsedWithConstraint', typesInferrer.numType);
+  checkType('listEscapingFromSetter', typesInferrer.numType);
+  checkType('listUsedInLocal', typesInferrer.numType);
+  checkType('listEscapingInSetterValue', typesInferrer.numType);
+  checkType('listEscapingInIndex', typesInferrer.numType);
+  checkType('listEscapingInIndexSet', typesInferrer.intType);
+  checkType('listEscapingTwiceInIndexSet', typesInferrer.numType);
+  checkType('listSetInNonFinalField', typesInferrer.numType);
+  checkType('listWithChangedLength', typesInferrer.intType.nullable());
 
   checkType('listPassedToClosure', typesInferrer.dynamicType);
   checkType('listReturnedFromClosure', typesInferrer.dynamicType);
@@ -215,6 +223,8 @@
   checkType('listPassedAsOptionalParameter', typesInferrer.dynamicType);
   checkType('listPassedAsNamedParameter', typesInferrer.dynamicType);
 
-  checkType('listUnset', new TypeMask.empty());
-  checkType('listOnlySetWithConstraint', new TypeMask.empty());
+  if (!allocation.contains('filled')) {
+    checkType('listUnset', new TypeMask.nonNullEmpty());
+    checkType('listOnlySetWithConstraint', new TypeMask.nonNullEmpty());
+  }
 }
diff --git a/tests/compiler/dart2js/memory_source_file_helper.dart b/tests/compiler/dart2js/memory_source_file_helper.dart
index 10f3102..987fff7 100644
--- a/tests/compiler/dart2js/memory_source_file_helper.dart
+++ b/tests/compiler/dart2js/memory_source_file_helper.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async' show Future;
 import 'dart:io';
-export 'dart:io' show Options;
+export 'dart:io' show Platform;
 
 export '../../../sdk/lib/_internal/compiler/implementation/apiimpl.dart'
        show Compiler;
diff --git a/tests/compiler/dart2js/mini_parser_test.dart b/tests/compiler/dart2js/mini_parser_test.dart
index 7227f28..dc2d642 100644
--- a/tests/compiler/dart2js/mini_parser_test.dart
+++ b/tests/compiler/dart2js/mini_parser_test.dart
@@ -10,7 +10,7 @@
 
 void main() {
   // Parse this script itself.
-  tool.toolMain(<String>[ new Options().script ]);
+  tool.toolMain(<String>[ Platform.script ]);
 }
 
 /** This class is unused but used to test mini_parser.dart. */
diff --git a/tests/compiler/dart2js/mirror_tree_shaking_test.dart b/tests/compiler/dart2js/mirror_tree_shaking_test.dart
index 4869c70..6287c12 100644
--- a/tests/compiler/dart2js/mirror_tree_shaking_test.dart
+++ b/tests/compiler/dart2js/mirror_tree_shaking_test.dart
@@ -16,7 +16,7 @@
 import 'dart:async';
 
 main() {
-  Uri script = currentDirectory.resolve(nativeToUriPath(new Options().script));
+  Uri script = currentDirectory.resolve(nativeToUriPath(Platform.script));
   Uri libraryRoot = script.resolve('../../../sdk/');
   Uri packageRoot = script.resolve('./packages/');
 
@@ -45,6 +45,7 @@
   Expect.isFalse(compiler.enqueuer.resolution.hasEnqueuedEverything);
   Expect.isFalse(compiler.enqueuer.codegen.hasEnqueuedEverything);
   Expect.isFalse(compiler.disableTypeInference);
+  Expect.isFalse(compiler.backend.hasRetainedMetadata);
 }
 
 const Map MEMORY_SOURCE_FILES = const {
diff --git a/tests/compiler/dart2js/mirrors_test.dart b/tests/compiler/dart2js/mirrors_test.dart
index 6fc2094..4090882 100644
--- a/tests/compiler/dart2js/mirrors_test.dart
+++ b/tests/compiler/dart2js/mirrors_test.dart
@@ -42,7 +42,7 @@
 
 main() {
   Uri scriptUri =
-      currentDirectory.resolve(nativeToUriPath(new Options().script));
+      currentDirectory.resolve(nativeToUriPath(Platform.script));
   Uri libUri = scriptUri.resolve('../../../sdk/');
   Uri inputUri = scriptUri.resolve('mirrors_helper.dart');
   var provider = new SourceFileProvider();
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 9fde6d6..1e9a796 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -73,7 +73,19 @@
   createRuntimeType(a) {}
   createInvocationMirror(a0, a1, a2, a3, a4, a5) {}
   throwNoSuchMethod(obj, name, arguments, expectedArgumentNames) {}
-  throwAbstractClassInstantiationError(className) {}''';
+  throwAbstractClassInstantiationError(className) {}
+  boolTypeCheck(value) {}
+  propertyTypeCheck(value, property) {}
+  interceptedTypeCheck(value, property) {}
+  functionSubtypeCast(Object object, String signatureName,
+                      String contextName, var context) {}
+  checkFunctionSubtype(var target, String signatureName,
+                       String contextName, var context,
+                       var typeArguments) {}
+  computeSignature(var signature, var context, var contextName) {}
+  defineNativeMethodsFinish() {}
+  getRuntimeTypeArguments(target, substitutionName) {}
+  voidTypeCheck(value) {}''';
 
 const String FOREIGN_LIBRARY = r'''
   dynamic JS(String typeDescription, String codeTemplate,
@@ -92,7 +104,7 @@
   abstract class JSMutableIndexable extends JSIndexable {}
   class JSArray extends Interceptor implements List, JSIndexable {
     var length;
-    operator[](index) {}
+    operator[](index) => this[index];
     operator[]=(index, value) {}
     var add;
   }
@@ -168,7 +180,10 @@
   abstract class StackTrace {}
   class Type {}
   class Function {}
-  class List<E> { List([length]); }
+  class List<E> {
+    List([length]);
+    List.filled(length, element);
+  }
   abstract class Map<K,V> {}
   class DateTime {
     DateTime(year);
diff --git a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
index eccf849..267f5fe 100644
--- a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
@@ -63,7 +63,7 @@
   checkReturn(String name, type) {
     var element = findElement(compiler, name);
     Expect.equals(type,
-        typesInferrer.internal.returnTypeOf[element].simplify(compiler));
+        typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
   }
 
   var subclassOfInterceptor =
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
index 23d6db0..0f10a24 100644
--- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
@@ -87,7 +87,7 @@
 
   checkReturn(String name, type) {
     var element = findElement(compiler, name);
-    Expect.equals(type, typesInferrer.internal.returnTypeOf[element]);
+    Expect.equals(type, typesInferrer.getReturnTypeOfElement(element));
   }
 
   checkReturn('returnInt1', typesInferrer.intType);
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
index e03c4f3..5904dee 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
@@ -32,7 +32,7 @@
   checkFieldTypeInClass(String className, String fieldName, type) {
     var cls = findElement(compiler, className);
     var element = cls.lookupLocalMember(buildSourceString(fieldName));
-    Expect.equals(type, typesInferrer.internal.typeOf[element]);
+    Expect.equals(type, typesInferrer.getTypeOfElement(element));
   }
 
   checkFieldTypeInClass('A', 'intField', typesInferrer.intType);
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
index 058187b..a4a4e1f 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
@@ -32,7 +32,7 @@
     var cls = findElement(compiler, className);
     var element = cls.lookupLocalMember(buildSourceString(fieldName));
     Expect.equals(type,
-        typesInferrer.internal.typeOf[element].simplify(compiler));
+        typesInferrer.getTypeOfElement(element).simplify(compiler));
   }
 
   checkFieldTypeInClass('A', 'dynamicField',
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
index 3108608..8cea159 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
@@ -35,7 +35,7 @@
     var cls = findElement(compiler, className);
     var element = cls.lookupLocalMember(buildSourceString(fieldName));
     Expect.equals(type,
-        typesInferrer.internal.typeOf[element].simplify(compiler));
+        typesInferrer.getTypeOfElement(element).simplify(compiler));
   }
 
   checkFieldTypeInClass('A', 'intField', typesInferrer.intType);
diff --git a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
index 400c0f8..f4589cd 100644
--- a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
@@ -103,12 +103,12 @@
     var element = findElement(compiler, name);
     Expect.equals(
         type,
-        typesInferrer.internal.returnTypeOf[element].simplify(compiler),
+        typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
         name);
   }
 
   checkReturn('test1', typesInferrer.intType);
-  checkReturn('test2', typesInferrer.dynamicType);
+  checkReturn('test2', typesInferrer.dynamicType.nonNullable());
   checkReturn('test3', typesInferrer.intType);
   checkReturn('test4', typesInferrer.mapType);
   checkReturn('test5', typesInferrer.dynamicType.nonNullable());
@@ -118,17 +118,13 @@
   compiler.runCompiler(uri);
   typesInferrer = compiler.typesTask.typesInferrer;
 
-  checkReturn('test1', typesInferrer.dynamicType);
+  checkReturn('test1', typesInferrer.dynamicType.nonNullable());
   checkReturn('test2', typesInferrer.mapType);
   checkReturn('test3', typesInferrer.mapType);
   checkReturn('test4', typesInferrer.mapType);
   checkReturn('test5', typesInferrer.mapType);
 
-  // TODO(ngeoffray): The reason for nullablity is because the
-  // inferrer thinks Object.noSuchMethod return null. Once we track
-  // aborting control flow in the analysis, we won't get the nullable
-  // anymore.
-  checkReturn('test6', typesInferrer.numType.nullable());
+  checkReturn('test6', typesInferrer.numType);
   checkReturn('test7', typesInferrer.intType);
   checkReturn('test8', typesInferrer.intType);
   checkReturn('test9', typesInferrer.intType);
diff --git a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
index cfae3a7..c5fbce1 100644
--- a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
@@ -70,7 +70,7 @@
     var cls = findElement(compiler, className);
     var element = cls.lookupLocalMember(buildSourceString(methodName));
     Expect.equals(type,
-        typesInferrer.internal.returnTypeOf[element].simplify(compiler));
+        typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
   }
 
   var subclassOfInterceptor =
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index cfd0ba8..b5b9d9b 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -351,8 +351,23 @@
   return b;
 }
 
+testReturnElementOfConstList1() {
+  return const [42][0];
+}
+
+testReturnElementOfConstList2() {
+  return topLevelConstList[0];
+}
+
+testReturnItselfOrInt(a) {
+  if (a) return 42;
+  return testReturnItselfOrInt(a);
+}
+
 testReturnInvokeDynamicGetter() => new A().myFactory();
 
+var topLevelConstList = const [42];
+
 get topLevelGetter => 42;
 returnDynamic() => topLevelGetter(42);
 returnTopLevelGetter() => topLevelGetter;
@@ -459,6 +474,9 @@
          ..returnInt7()
          ..returnInt8()
          ..returnInt9();
+  testReturnElementOfConstList1();
+  testReturnElementOfConstList2();
+  testReturnItselfOrInt(topLevelGetter());
   testReturnInvokeDynamicGetter();
 }
 """;
@@ -473,7 +491,7 @@
     var element = findElement(compiler, name);
     Expect.equals(
         type,
-        typesInferrer.internal.returnTypeOf[element].simplify(compiler),
+        typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
         name);
   }
   var interceptorType =
@@ -532,13 +550,16 @@
   checkReturn('testBreak1', interceptorType.nullable());
   checkReturn('testContinue2', interceptorType.nullable());
   checkReturn('testBreak2', typesInferrer.intType.nullable());
+  checkReturn('testReturnElementOfConstList1', typesInferrer.intType);
+  checkReturn('testReturnElementOfConstList2', typesInferrer.intType);
+  checkReturn('testReturnItselfOrInt', typesInferrer.intType);
   checkReturn('testReturnInvokeDynamicGetter', typesInferrer.dynamicType);
 
   checkReturnInClass(String className, String methodName, type) {
     var cls = findElement(compiler, className);
     var element = cls.lookupLocalMember(buildSourceString(methodName));
     Expect.equals(type,
-        typesInferrer.internal.returnTypeOf[element].simplify(compiler));
+        typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
   }
 
   checkReturnInClass('A', 'returnInt1', typesInferrer.intType);
@@ -563,7 +584,7 @@
     var cls = findElement(compiler, className);
     var element = cls.localLookup(buildSourceString(className));
     Expect.equals(new TypeMask.nonNullExact(cls.rawType),
-                  typesInferrer.internal.returnTypeOf[element]);
+                  typesInferrer.getReturnTypeOfElement(element));
   }
   checkFactoryConstructor('A');
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
index 917ffe9..18eddc7 100644
--- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
@@ -162,7 +162,7 @@
   checkReturn(String name, type) {
     var element = findElement(compiler, name);
     Expect.equals(type,
-        typesInferrer.internal.returnTypeOf[element].simplify(compiler));
+        typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
   }
 
   checkReturn('returnInt1', typesInferrer.intType);
diff --git a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart b/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
index 0341df4..020f4c6 100644
--- a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
@@ -38,7 +38,7 @@
   checkReturnInClass(String className, String methodName, type) {
     var cls = findElement(compiler, className);
     var element = cls.lookupLocalMember(buildSourceString(methodName));
-    Expect.equals(type, typesInferrer.internal.returnTypeOf[element]);
+    Expect.equals(type, typesInferrer.getReturnTypeOfElement(element));
   }
 
   checkReturnInClass('A', '+', typesInferrer.intType);
diff --git a/tests/compiler/dart2js/subtype_test.dart b/tests/compiler/dart2js/subtype_test.dart
index b4efe86..35a4651 100644
--- a/tests/compiler/dart2js/subtype_test.dart
+++ b/tests/compiler/dart2js/subtype_test.dart
@@ -264,6 +264,7 @@
 
 testFunctionSubtyping() {
   var env = new TypeEnvironment(r"""
+      _() => null;
       void void_() {}
       void void_2() {}
       int int_() => 0;
@@ -285,6 +286,7 @@
 
 testTypedefSubtyping() {
   var env = new TypeEnvironment(r"""
+      typedef _();
       typedef void void_();
       typedef void void_2();
       typedef int int_();
@@ -317,6 +319,13 @@
   // Function <: () -> int
   expect(false, 'Function', 'int_');
 
+  // () -> dynamic <: () -> dynamic
+  expect(true, '_', '_');
+  // () -> dynamic <: () -> void
+  expect(true, '_', 'void_');
+  // () -> void <: () -> dynamic
+  expect(true, 'void_', '_');
+
   // () -> int <: () -> void
   expect(true, 'int_', 'void_');
   // () -> void <: () -> int
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 08a8630..c10aa77 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -46,7 +46,8 @@
                 testThis,
                 testSuper,
                 testOperatorsAssignability,
-                testFieldInitializers];
+                testFieldInitializers,
+                testTypeVariableExpressions];
   for (Function test in tests) {
     setup();
     test();
@@ -1025,6 +1026,25 @@
                      }""", MessageKind.NOT_ASSIGNABLE);
 }
 
+void testTypeVariableExpressions() {
+  String script = """class Foo<T> {
+                       void method() {}
+                     }""";
+  LibraryElement library = mockLibrary(compiler, script);
+  compiler.parseScript(script, library);
+  ClassElement foo = library.find(const SourceString("Foo"));
+  foo.ensureResolved(compiler);
+  Element method = foo.lookupLocalMember(const SourceString('method'));
+
+  analyzeIn(method, "{ Type type = T; }");
+  analyzeIn(method, "{ T type = T; }", MessageKind.NOT_ASSIGNABLE);
+  analyzeIn(method, "{ int type = T; }", MessageKind.NOT_ASSIGNABLE);
+
+  analyzeIn(method, "{ String typeName = T.toString(); }");
+  analyzeIn(method, "{ T.foo; }", MessageKind.PROPERTY_NOT_FOUND);
+  analyzeIn(method, "{ T.foo(); }", MessageKind.METHOD_NOT_FOUND);
+  analyzeIn(method, "{ T + 1; }", MessageKind.OPERATOR_NOT_FOUND);
+}
 
 const CLASS_WITH_METHODS = '''
 class ClassWithMethods {
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/type_representation_test.dart
index 132d3a7..1c946ee 100644
--- a/tests/compiler/dart2js/type_representation_test.dart
+++ b/tests/compiler/dart2js/type_representation_test.dart
@@ -10,7 +10,7 @@
 import '../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart'
        show Element, ClassElement;
 import '../../../sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart'
-       show TypeRepresentationGenerator;
+       show JavaScriptBackend, TypeRepresentationGenerator;
 
 void main() {
   testTypeRepresentations();
@@ -42,6 +42,14 @@
     Expect.stringEquals(expectedRepresentation, foundRepresentation);
   }
 
+  JavaScriptBackend backend = env.compiler.backend;
+  String func = backend.namer.functionTypeTag();
+  String retvoid = backend.namer.functionTypeVoidReturnTag();
+  String ret = backend.namer.functionTypeReturnTypeTag();
+  String args = backend.namer.functionTypeRequiredParametersTag();
+  String opt = backend.namer.functionTypeOptionalParametersTag();
+  String named = backend.namer.functionTypeNamedParametersTag();
+
   ClassElement List_ = env.getElement('List');
   TypeVariableType List_E = List_.typeVariables.head;
   ClassElement Map_ = env.getElement('Map');
@@ -77,7 +85,7 @@
   // List<int>
   expect('[$List_rep, $int_rep]', instantiate(List_, [int_]));
   // List<Typedef>
-  expect('[$List_rep, {func: true, retvoid: true}]',
+  expect('[$List_rep, {$func: "void_", $retvoid: true}]',
       instantiate(List_, [Typedef_]));
 
   // Map<K,V>
@@ -91,46 +99,51 @@
       instantiate(Map_, [int_, String_]));
 
   // void m1() {}
-  expect("{func: true, retvoid: true}",
+  expect('{$func: "void_", $retvoid: true}',
       env.getElement('m1').computeType(env.compiler));
 
   // int m2() => 0;
-  expect("{func: true, ret: $int_rep}",
+  expect('{$func: "int_", $ret: $int_rep}',
       env.getElement('m2').computeType(env.compiler));
 
   // List<int> m3() => null;
-  expect("{func: true, ret: [$List_rep, $int_rep]}",
+  expect('{$func: "List_", $ret: [$List_rep, $int_rep]}',
       env.getElement('m3').computeType(env.compiler));
 
   // m4() {}
-  expect("{func: true}",
+  expect('{$func: "dynamic_"}',
       env.getElement('m4').computeType(env.compiler));
 
   // m5(int a, String b) {}
-  expect("{func: true, args: [$int_rep, $String_rep]}",
+  expect('{$func: "dynamic__int_String", $args: [$int_rep, $String_rep]}',
       env.getElement('m5').computeType(env.compiler));
 
   // m6(int a, [String b]) {}
-  expect("{func: true, args: [$int_rep], opt: [$String_rep]}",
+  expect('{$func: "dynamic__int__String", $args: [$int_rep],'
+         ' $opt: [$String_rep]}',
       env.getElement('m6').computeType(env.compiler));
 
   // m7(int a, String b, [List<int> c, d]) {}
-  expect("{func: true, args: [$int_rep, $String_rep],"
-         " opt: [[$List_rep, $int_rep], null]}",
+  expect('{$func: "dynamic__int_String__List_dynamic",'
+         ' $args: [$int_rep, $String_rep],'
+         ' $opt: [[$List_rep, $int_rep], null]}',
       env.getElement('m7').computeType(env.compiler));
 
   // m8(int a, {String b}) {}
-  expect("{func: true, args: [$int_rep], named: {b: $String_rep}}",
+  expect('{$func: "dynamic__int__String0",'
+         ' $args: [$int_rep], $named: {b: $String_rep}}',
       env.getElement('m8').computeType(env.compiler));
 
   // m9(int a, String b, {List<int> c, d}) {}
-  expect("{func: true, args: [$int_rep, $String_rep],"
-         " named: {c: [$List_rep, $int_rep], d: null}}",
+  expect('{$func: "dynamic__int_String__List_dynamic0",'
+         ' $args: [$int_rep, $String_rep],'
+         ' $named: {c: [$List_rep, $int_rep], d: null}}',
       env.getElement('m9').computeType(env.compiler));
 
   // m10(void f(int a, [b])) {}
-  expect("{func: true, args:"
-         " [{func: true, retvoid: true, args: [$int_rep], opt: [null]}]}",
+  expect('{$func: "dynamic__void__int__dynamic", $args:'
+         ' [{$func: "void__int__dynamic",'
+         ' $retvoid: true, $args: [$int_rep], $opt: [null]}]}',
       env.getElement('m10').computeType(env.compiler));
 }
 
diff --git a/tests/compiler/dart2js/unneeded_part_js_test.dart b/tests/compiler/dart2js/unneeded_part_js_test.dart
index aa1e641..cebcd91 100644
--- a/tests/compiler/dart2js/unneeded_part_js_test.dart
+++ b/tests/compiler/dart2js/unneeded_part_js_test.dart
@@ -16,7 +16,7 @@
 import 'dart:async';
 
 main() {
-  Uri script = currentDirectory.resolve(nativeToUriPath(new Options().script));
+  Uri script = currentDirectory.resolve(nativeToUriPath(Platform.script));
   Uri libraryRoot = script.resolve('../../../sdk/');
   Uri packageRoot = script.resolve('./packages/');
 
diff --git a/tests/compiler/dart2js_foreign/dart2js_foreign.status b/tests/compiler/dart2js_foreign/dart2js_foreign.status
index d383e88..d5919cc 100644
--- a/tests/compiler/dart2js_foreign/dart2js_foreign.status
+++ b/tests/compiler/dart2js_foreign/dart2js_foreign.status
@@ -55,6 +55,12 @@
 native_window1_test: Pass # For the wrong reason.
 native_window2_test: Pass # For the wrong reason.
 
+native_checked_fields_test: Fail # TODO(ahe): Convert to metadata syntax.
+native_class_inheritance4_test: Fail # TODO(ahe): Convert to metadata syntax.
+native_class_with_dart_methods_test: Fail # TODO(ahe): Convert to metadata syntax.
+native_missing_method1_test: Fail # TODO(ahe): Convert to metadata syntax.
+native_missing_method2_test: Fail # TODO(ahe): Convert to metadata syntax.
+native_to_string_test: Fail # TODO(ahe): Convert to metadata syntax.
 
 [ $compiler == dartc || $browser ]
 *: Skip
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 6bd2384..9c67dd2 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -111,4 +111,11 @@
 *: Skip
 
 [ $arch == simmips ]
-*: Skip
+int_parse_radix_test: Skip # Timeout
+
+[ $arch == simmips && $checked ]
+hash_map2_test: Crash # Too far PC relative branch.
+collection_length_test: Skip # Timeout.
+
+[ $arch == simmips && $mode == debug ]
+collection_to_string_test: Pass, Crash # Issue: 11207
diff --git a/tests/corelib/duration_big_num_test.dart b/tests/corelib/duration_big_num_test.dart
new file mode 100644
index 0000000..789982d
--- /dev/null
+++ b/tests/corelib/duration_big_num_test.dart
@@ -0,0 +1,22 @@
+// 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:expect/expect.dart";
+import 'dart:math';
+
+main() {
+  Duration d, d1;
+
+  d1 = new Duration(microseconds: pow(2, 53));
+  d = d1 * 2;
+  Expect.equals(pow(2, 54), d.inMicroseconds);
+  d = d1 * 1.5;
+  Expect.equals(pow(2, 53).toDouble() * 1.5, d.inMicroseconds);
+  Expect.isTrue(d.inMicroseconds is int);
+
+  // Test that we lose precision when multiplying with a double.
+  d = new Duration(microseconds: pow(2, 53) + 1) * 1.0;
+  Expect.equals(0, d.inMicroseconds % 2);
+}
+
diff --git a/tests/corelib/duration_double_multiplication_test.dart b/tests/corelib/duration_double_multiplication_test.dart
new file mode 100644
index 0000000..74ce559
--- /dev/null
+++ b/tests/corelib/duration_double_multiplication_test.dart
@@ -0,0 +1,20 @@
+// 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:expect/expect.dart";
+
+main() {
+  Duration d, d1;
+
+  d1 = new Duration(milliseconds: 1);
+  d = d1 * 0.005;
+  Expect.equals(1000 * 0.005, d.inMicroseconds);
+  d = d1 * 0.0;
+  Expect.equals(0, d.inMicroseconds);
+  d = d1 * -0.005;
+  Expect.equals(1000 * -0.005, d.inMicroseconds);
+  d = d1 * 0.0015;
+  Expect.equals((1000 * 0.0015).round(), d.inMicroseconds);
+
+}
diff --git a/tests/corelib/iterable_contains2_test.dart b/tests/corelib/iterable_contains2_test.dart
new file mode 100644
index 0000000..889ad2d
--- /dev/null
+++ b/tests/corelib/iterable_contains2_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 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.
+
+import "package:expect/expect.dart";
+
+// Tests for the contains methods on lists.
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  var list = <B>[ new B() ];
+  var set = new Set<B>();
+  set.add(new B());
+  var iterable1 = list.map((x) => x);
+  var iterable2 = list.take(1);
+  var list2 = const <B>[ const B() ];
+  var iterable3 = list2.map((x) => x);
+  var iterable4 = list2.take(1);
+  var iterables =
+      [ list, set, iterable1, iterable2, list2, iterable3, iterable4 ];
+  for (var iterable in iterables) {
+    Expect.isFalse(iterable.contains(new A()));
+  }
+}
diff --git a/tests/corelib/iterable_skip_test.dart b/tests/corelib/iterable_skip_test.dart
index 2910d3b..59d604d 100644
--- a/tests/corelib/iterable_skip_test.dart
+++ b/tests/corelib/iterable_skip_test.dart
@@ -254,5 +254,6 @@
     testSkipTake(collection, 15, 5);
     testSkipTake(collection, 20, 0);
     testSkipTake(collection, 20, 5);
+    Expect.throws(() => longList.skip(-1), (e) => e is RangeError);
   }
 }
diff --git a/tests/corelib/iterable_take_test.dart b/tests/corelib/iterable_take_test.dart
index eda953a..fdedb93 100644
--- a/tests/corelib/iterable_take_test.dart
+++ b/tests/corelib/iterable_take_test.dart
@@ -215,4 +215,15 @@
   Expect.isNull(it.current);
   Expect.isFalse(it.moveNext());
   Expect.isNull(it.current);
+
+  Expect.throws(() => list1.skip(-1), (e) => e is RangeError);
+  Expect.throws(() => list2.skip(-1), (e) => e is RangeError);
+  Expect.throws(() => list3.skip(-1), (e) => e is RangeError);
+  Expect.throws(() => set1.skip(-1), (e) => e is RangeError);
+  Expect.throws(() => set2.skip(-1), (e) => e is RangeError);
+  Expect.throws(() => list1.map((x) => x).skip(-1), (e) => e is RangeError);
+  Expect.throws(() => list2.map((x) => x).skip(-1), (e) => e is RangeError);
+  Expect.throws(() => list3.map((x) => x).skip(-1), (e) => e is RangeError);
+  Expect.throws(() => set1.map((x) => x).skip(-1), (e) => e is RangeError);
+  Expect.throws(() => set2.map((x) => x).skip(-1), (e) => e is RangeError);
 }
diff --git a/tests/corelib/list_filled_type_argument_test.dart b/tests/corelib/list_filled_type_argument_test.dart
new file mode 100644
index 0000000..6d361cc
--- /dev/null
+++ b/tests/corelib/list_filled_type_argument_test.dart
@@ -0,0 +1,11 @@
+// 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:expect/expect.dart";
+
+main() {
+  var a = new List<int>.filled(42, 42);
+  Expect.isTrue(a is List<int>);
+  Expect.isFalse(a is List<String>);
+}
diff --git a/tests/corelib/list_index_of2_test.dart b/tests/corelib/list_index_of2_test.dart
new file mode 100644
index 0000000..56aec92
--- /dev/null
+++ b/tests/corelib/list_index_of2_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A { const A(); }
+class B extends A { const B(); }
+
+void test(List<B> list) {
+  // Test that the list accepts a different type for indexOf.
+  //   List<B>.indexOf(A)
+  Expect.equals(-1, list.indexOf(const A()));
+  Expect.equals(-1, list.lastIndexOf(const A()));
+}
+
+main() {
+  var list = new List<B>(1);
+  list[0] = const B();
+  test(list);
+  var list2 = new List<B>();
+  list2.add(const B());
+  test(list2);
+  test(<B>[const B()]);
+  test(const <B>[]);
+  test(<B>[const B()].toList());
+}
diff --git a/tests/corelib/list_index_of_test.dart b/tests/corelib/list_index_of_test.dart
index 4641adc..ebb2731 100644
--- a/tests/corelib/list_index_of_test.dart
+++ b/tests/corelib/list_index_of_test.dart
@@ -4,38 +4,32 @@
 
 import "package:expect/expect.dart";
 
-class ListIndexOfTest {
-  static testMain() {
-    test(new List<int>(5));
-    var l = new List<int>();
-    l.length = 5;
-    test(l);
-  }
-
-  static void test(List<int> list) {
-    list[0] = 1;
-    list[1] = 2;
-    list[2] = 3;
-    list[3] = 4;
-    list[4] = 1;
-
-    Expect.equals(3, list.indexOf(4, 0));
-    Expect.equals(0, list.indexOf(1, 0));
-    Expect.equals(4, list.lastIndexOf(1, list.length - 1));
-
-    Expect.equals(4, list.indexOf(1, 1));
-    Expect.equals(-1, list.lastIndexOf(4, 2));
-
-    Expect.equals(3, list.indexOf(4, 2));
-    Expect.equals(3, list.indexOf(4, -5));
-    Expect.equals(-1, list.indexOf(4, 50));
-
-    Expect.equals(-1, list.lastIndexOf(4, 2));
-    Expect.equals(-1, list.lastIndexOf(4, -5));
-    Expect.equals(3, list.lastIndexOf(4, 50));
-  }
+main() {
+  test(new List<int>(5));
+  var l = new List<int>();
+  l.length = 5;
+  test(l);
 }
 
-main() {
-  ListIndexOfTest.testMain();
+void test(List<int> list) {
+  list[0] = 1;
+  list[1] = 2;
+  list[2] = 3;
+  list[3] = 4;
+  list[4] = 1;
+
+  Expect.equals(3, list.indexOf(4, 0));
+  Expect.equals(0, list.indexOf(1, 0));
+  Expect.equals(4, list.lastIndexOf(1, list.length - 1));
+
+  Expect.equals(4, list.indexOf(1, 1));
+  Expect.equals(-1, list.lastIndexOf(4, 2));
+
+  Expect.equals(3, list.indexOf(4, 2));
+  Expect.equals(3, list.indexOf(4, -5));
+  Expect.equals(-1, list.indexOf(4, 50));
+
+  Expect.equals(-1, list.lastIndexOf(4, 2));
+  Expect.equals(-1, list.lastIndexOf(4, -5));
+  Expect.equals(3, list.lastIndexOf(4, 50));
 }
diff --git a/tests/corelib/map_contains_key_test.dart b/tests/corelib/map_contains_key_test.dart
new file mode 100644
index 0000000..32fd3db
--- /dev/null
+++ b/tests/corelib/map_contains_key_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  var map1 = new Map<B, B>();
+  map1[const B()] = const B();
+  var map2 = new Map<B, B>();
+  var list = <B>[ const B() ];
+
+  var maps = [map1, map2];
+  for (var map in maps) {
+    // Test that the map accepts a key is not of the same type:
+    //   Map<B, ?>.containsValue(A)
+    Expect.isFalse(map.containsKey(new A()));
+  }
+}
diff --git a/tests/corelib/map_contains_value_test.dart b/tests/corelib/map_contains_value_test.dart
new file mode 100644
index 0000000..84f02ae
--- /dev/null
+++ b/tests/corelib/map_contains_value_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  var map1 = new Map<B, B>();
+  map1[const B()] = const B();
+  var map2 = new Map<B, B>();
+  var list = <B>[ const B() ];
+  Map<int, B> map3 = list.asMap();
+
+  var maps = [map1, map2, map3];
+  for (var map in maps) {
+    // Test that the map accepts a value is not of the same type:
+    //   Map<?, B>.containsValue(A)
+    Expect.isFalse(map.containsValue(new A()));
+  }
+}
diff --git a/tests/corelib/map_index_test.dart b/tests/corelib/map_index_test.dart
new file mode 100644
index 0000000..5a0fc9a
--- /dev/null
+++ b/tests/corelib/map_index_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  var map1 = new Map<B, B>();
+  map1[const B()] = const B();
+  var map2 = new Map<B, B>();
+  var list = <B>[ const B() ];
+
+  var maps = [map1, map2];
+  for (var map in maps) {
+    // Test that the map accepts a key is not of the same type:
+    //   Map<B, ?>[A]
+    Expect.isNull(map[new A()]);
+  }
+}
diff --git a/tests/corelib/map_remove_test.dart b/tests/corelib/map_remove_test.dart
new file mode 100644
index 0000000..eecebf7
--- /dev/null
+++ b/tests/corelib/map_remove_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  var map1 = new Map<B, B>();
+  map1[const B()] = const B();
+  var map2 = new Map<B, B>();
+  var list = <B>[ const B() ];
+
+  var maps = [map1, map2];
+  for (var map in maps) {
+    // Test that the map accepts a key is not of the same type:
+    //   Map<B, ?>.remove(A)
+    Expect.isNull(map.remove(new A()));
+  }
+}
diff --git a/tests/corelib/set_containsAll_test.dart b/tests/corelib/set_containsAll_test.dart
new file mode 100644
index 0000000..9f6bae8d
--- /dev/null
+++ b/tests/corelib/set_containsAll_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  var set1 = new Set<B>();
+  set1.add(const B());
+  var set2 = new Set<B>();
+  var list = <B>[ const B() ];
+  var set3 = list.toSet();
+
+  var sets = [set1, set2, set3];
+  for (var setToTest in sets) {
+    Expect.isFalse(setToTest.containsAll(<A>[new A()]));
+  }
+}
diff --git a/tests/corelib/set_contains_test.dart b/tests/corelib/set_contains_test.dart
new file mode 100644
index 0000000..07670a3
--- /dev/null
+++ b/tests/corelib/set_contains_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  var set1 = new Set<B>();
+  set1.add(const B());
+  var set2 = new Set<B>();
+  var list = <B>[ const B() ];
+  var set3 = list.toSet();
+
+  var sets = [set1, set2, set3];
+  for (var setToTest in sets) {
+    // Test that the set accepts a value that is not of the same type
+    //   Set<B>.contains(A)
+    Expect.isFalse(setToTest.contains(new A()));
+  }
+}
diff --git a/tests/corelib/set_intersection_test.dart b/tests/corelib/set_intersection_test.dart
new file mode 100644
index 0000000..bdfdda6
--- /dev/null
+++ b/tests/corelib/set_intersection_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  var set1 = new Set<B>();
+  set1.add(const B());
+  var set2 = new Set<B>();
+  var list = <B>[ const B() ];
+  var set3 = list.toSet();
+
+  var setOther = new Set<A>();
+  setOther.add(new A());
+  var sets = [set1, set2, set3];
+  for (var setToTest in sets) {
+    // Test that the set accepts another set that is not of the same type:
+    //   Set<B>.intersection(Set<A>)
+    Set result = setToTest.intersection(setOther);
+    Expect.isTrue(result.isEmpty);
+  }
+}
diff --git a/tests/corelib/set_removeAll_test.dart b/tests/corelib/set_removeAll_test.dart
new file mode 100644
index 0000000..abd4a2d
--- /dev/null
+++ b/tests/corelib/set_removeAll_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  var set1 = new Set<B>();
+  set1.add(const B());
+  var set2 = new Set<B>();
+  var list = <B>[ const B() ];
+  var set3 = list.toSet();
+
+  var sets = [set1, set2, set3];
+  for (var setToTest in sets) {
+    // Test that the set accepts a list that is not of the same type:
+    //   Set<B>.removeAll(List<A>)
+    Expect.isNull(setToTest.removeAll(<A>[new A()]));
+  }
+}
diff --git a/tests/corelib/set_remove_test.dart b/tests/corelib/set_remove_test.dart
new file mode 100644
index 0000000..de99304
--- /dev/null
+++ b/tests/corelib/set_remove_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  var set1 = new Set<B>();
+  set1.add(const B());
+  var set2 = new Set<B>();
+  var list = <B>[ const B() ];
+  var set3 = list.toSet();
+
+  var sets = [set1, set2, set3];
+  for (var setToTest in sets) {
+    // Test that the set accepts a value that is not of the same type
+    //   Set<B>.remove(A)
+    Expect.isFalse(setToTest.remove(new A()));
+  }
+}
diff --git a/tests/corelib/set_retainAll_test.dart b/tests/corelib/set_retainAll_test.dart
new file mode 100644
index 0000000..bd207f8
--- /dev/null
+++ b/tests/corelib/set_retainAll_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  var set1 = new Set<B>();
+  set1.add(const B());
+  var set2 = new Set<B>();
+  var list = <B>[ const B() ];
+  var set3 = list.toSet();
+
+  var sets = [set1, set2, set3];
+  for (var setToTest in sets) {
+    // Test that the set accepts a list that is not of the same type:
+    //   Set<B>.retainAll(List<A>)
+    setToTest.retainAll(<A>[new A()]);
+  }
+}
diff --git a/tests/corelib/string_test.dart b/tests/corelib/string_test.dart
index 4519733..aeb00c3 100644
--- a/tests/corelib/string_test.dart
+++ b/tests/corelib/string_test.dart
@@ -127,6 +127,29 @@
     Expect.isTrue("".startsWith(""));
     Expect.isFalse("".startsWith("s"));
 
+    Expect.isFalse("strstr".startsWith("s", 1));
+    Expect.isFalse("strstr".startsWith("s", 2));
+    Expect.isTrue("strstr".startsWith("s", 3));
+    Expect.isFalse("strstr".startsWith("s", 4));
+
+    Expect.isFalse("strstr".startsWith("st", 1));
+    Expect.isFalse("strstr".startsWith("st", 2));
+    Expect.isTrue("strstr".startsWith("st", 3));
+    Expect.isFalse("strstr".startsWith("st", 4));
+
+    Expect.isFalse("strstr".startsWith("str", 1));
+    Expect.isFalse("strstr".startsWith("str", 2));
+    Expect.isTrue("strstr".startsWith("str", 3));
+    Expect.isFalse("strstr".startsWith("str", 4));
+
+    Expect.isTrue("str".startsWith("", 0));
+    Expect.isTrue("str".startsWith("", 1));
+    Expect.isTrue("str".startsWith("", 2));
+    Expect.isTrue("str".startsWith("", 3));
+
+    Expect.throws(() => "str".startsWith("", -1));
+    Expect.throws(() => "str".startsWith("", 4));
+
     var regexp = new RegExp("s(?:tr?)?");
     Expect.isTrue("s".startsWith(regexp));
     Expect.isTrue("st".startsWith(regexp));
@@ -140,6 +163,30 @@
 
     Expect.isTrue("".startsWith(new RegExp("")));
     Expect.isTrue("".startsWith(new RegExp("a?")));
+
+    Expect.isFalse("strstr".startsWith(regexp, 1));
+    Expect.isFalse("strstr".startsWith(regexp, 2));
+    Expect.isTrue("strstr".startsWith(regexp, 3));
+    Expect.isFalse("strstr".startsWith(regexp, 4));
+
+    Expect.isTrue("str".startsWith(new RegExp(""), 0));
+    Expect.isTrue("str".startsWith(new RegExp(""), 1));
+    Expect.isTrue("str".startsWith(new RegExp(""), 2));
+    Expect.isTrue("str".startsWith(new RegExp(""), 3));
+    Expect.isTrue("str".startsWith(new RegExp("a?"), 0));
+    Expect.isTrue("str".startsWith(new RegExp("a?"), 1));
+    Expect.isTrue("str".startsWith(new RegExp("a?"), 2));
+    Expect.isTrue("str".startsWith(new RegExp("a?"), 3));
+
+    Expect.throws(() => "str".startsWith(regexp, -1));
+    Expect.throws(() => "str".startsWith(regexp, 4));
+
+    regexp = new RegExp("^str");
+    Expect.isTrue("strstr".startsWith(regexp));
+    Expect.isTrue("strstr".startsWith(regexp, 0));
+    Expect.isFalse("strstr".startsWith(regexp, 1));
+    Expect.isFalse("strstr".startsWith(regexp, 2));
+    Expect.isFalse("strstr".startsWith(regexp, 3));  // Second "str" isn't at ^.
   }
 
   static testIndexOf() {
diff --git a/tests/html/custom_element_bindings_test.dart b/tests/html/custom_element_bindings_test.dart
index 3b9d6a9..6548a7f 100644
--- a/tests/html/custom_element_bindings_test.dart
+++ b/tests/html/custom_element_bindings_test.dart
@@ -261,9 +261,9 @@
 
   AttributeMapWrapper(this._map);
 
-  bool containsValue(V value) => _map.containsValue(value);
-  bool containsKey(K key) => _map.containsKey(key);
-  V operator [](K key) => _map[key];
+  bool containsValue(Object value) => _map.containsValue(value);
+  bool containsKey(Object key) => _map.containsKey(key);
+  V operator [](Object key) => _map[key];
 
   void operator []=(K key, V value) {
     log.add(['[]=', key, value]);
@@ -272,7 +272,7 @@
 
   V putIfAbsent(K key, V ifAbsent()) => _map.putIfAbsent(key, ifAbsent);
 
-  V remove(K key) {
+  V remove(Object key) {
     log.add(['remove', key]);
     _map.remove(key);
   }
diff --git a/tests/html/document_test.dart b/tests/html/document_test.dart
index fece53e..ca04a0f 100644
--- a/tests/html/document_test.dart
+++ b/tests/html/document_test.dart
@@ -61,5 +61,24 @@
       expect(new Element.tag('a'), isAnchorElement);
       expect(new Element.tag('bad_name'), isUnknownElement);
     });
+
+    test('adoptNode', () {
+      var div = new Element.html('<div><div id="foo">bar</div></div>');
+      var doc = document.implementation.createHtmlDocument('');
+      expect(doc.adoptNode(div), div);
+      expect(div.document, doc);
+      doc.body.nodes.add(div);
+      expect(doc.query('#foo').text, 'bar');
+    });
+
+    test('importNode', () {
+      var div = new Element.html('<div><div id="foo">bar</div></div>');
+      var doc = document.implementation.createHtmlDocument('');
+      var div2 = doc.importNode(div, true);
+      expect(div2, isNot(equals(div)));
+      expect(div2.document, doc);
+      doc.body.nodes.add(div2);
+      expect(doc.query('#foo').text, 'bar');
+    });
   });
 }
diff --git a/tests/html/html.status b/tests/html/html.status
index 545b4c4..9aa3976 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -16,6 +16,9 @@
 [ $compiler == none && $runtime == drt && $system == windows ]
 worker_test/functional: Pass, Crash # Issue 9929.
 
+[ $compiler == dart2js && $checked ]
+template_element_test: Fail # BUG(11480): Triage.
+
 [ $compiler == dart2js && ($runtime == ie9 || $runtime == ie10 || $runtime == safari || $runtime == ff || $runtime == chrome || $runtime == chromeOnAndroid || $runtime == opera || $runtime == drt || $runtime == dartium)]
 dom_isolates_test: Skip # Need to migrate to new spawnDomFunction.
 
@@ -137,6 +140,7 @@
 window_open_test: Skip      # BUG(4016)
 canvasrenderingcontext2d_test/drawImage_video_element: Fail # IE does not support drawImage w/ video element
 canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Fail # IE does not support drawImage w/ video element
+canvasrenderingcontext2d_test/drawImage_image_element: Pass, Fail # Issue: 11416
 input_element_test/attributes: Fail # IE returns null while others ''
 
 # IE9 Feature support statuses-
@@ -366,9 +370,3 @@
 postmessage_structured_test: Skip  # Test cannot run under CSP restrictions (times out).
 safe_dom_test: Skip                # Test cannot run under CSP restrictions (times out).
 shadow_dom_layout_test: Fail, OK   # Test cannot run under CSP restrictions.
-
-[ $compiler == dartanalyzer ]
-path_observer_test: Fail
-
-[ $compiler == dart2analyzer ]
-path_observer_test: Fail
diff --git a/tests/html/indexeddb_2_test.dart b/tests/html/indexeddb_2_test.dart
index 03a0fd4..d197585 100644
--- a/tests/html/indexeddb_2_test.dart
+++ b/tests/html/indexeddb_2_test.dart
@@ -23,22 +23,22 @@
 
   var db;
   // Delete any existing DBs.
-  return html.window.indexedDB.deleteDatabase(dbName).then((_) {
+  return html.window.indexedDB.deleteDatabase(dbName).then(expectAsync1((_) {
       return html.window.indexedDB.open(dbName, version: version,
         onUpgradeNeeded: createObjectStore);
-    }).then((result) {
+    })).then(expectAsync1((result) {
       db = result;
       var transaction = db.transaction([storeName], 'readwrite');
       transaction.objectStore(storeName).put(value, key);
 
       return transaction.completed;
-    }).then((db) {
+    })).then(expectAsync1((db) {
       var transaction = db.transaction(storeName, 'readonly');
       return transaction.objectStore(storeName).getObject(key);
-    }).then((object) {
+    })).then(expectAsync1((object) {
       db.close();
       check(value, object);
-    }).catchError((e) {
+    })).catchError((e) {
       if (db != null) {
         db.close();
       }
diff --git a/tests/isolate/global_error_handler2_test.dart b/tests/isolate/global_error_handler2_test.dart
index c0b1241..d038f88 100644
--- a/tests/isolate/global_error_handler2_test.dart
+++ b/tests/isolate/global_error_handler2_test.dart
@@ -7,6 +7,7 @@
 import 'package:expect/expect.dart';
 import 'dart:async';
 import 'dart:isolate';
+import '../async_helper.dart';
 
 runTest() {
   SendPort mainIsolate;
@@ -34,9 +35,11 @@
   SendPort otherIsolate = spawnFunction(runTest, globalErrorHandler);
   otherIsolate.send(port.toSendPort());
   otherIsolate.send("message 2");
+  asyncStart();
   port.receive((msg, replyPort) {
     Expect.equals("received", msg);
     port.close();
     timer.cancel();
+    asyncEnd();
   });
 }
diff --git a/tests/isolate/global_error_handler_stream2_test.dart b/tests/isolate/global_error_handler_stream2_test.dart
index b1093f5..8590046 100644
--- a/tests/isolate/global_error_handler_stream2_test.dart
+++ b/tests/isolate/global_error_handler_stream2_test.dart
@@ -7,6 +7,7 @@
 import 'package:expect/expect.dart';
 import 'dart:async';
 import 'dart:isolate';
+import '../async_helper.dart';
 
 runTest() {
   IsolateSink mainIsolate;
@@ -37,10 +38,16 @@
   // the handling of the previous event. We therefore delay the closing.
   // Note: if the done is sent too early it won't lead to failing tests, but
   // just won't make sure that the globalErrorHandler works.
-  new Timer(const Duration(milliseconds: 10), otherIsolate.close);
+  asyncStart();
+  new Timer(const Duration(milliseconds: 10), () {
+    otherIsolate.close();
+    asyncEnd();
+  });
+  asyncStart();
   box.stream.single.then((msg) {
     Expect.equals("received done", msg);
     timer.cancel();
     keepRunningBox.stream.close();
+    asyncEnd();
   });
 }
diff --git a/tests/isolate/illegal_msg_stream_test.dart b/tests/isolate/illegal_msg_stream_test.dart
index bcc9135..2271ed5 100644
--- a/tests/isolate/illegal_msg_stream_test.dart
+++ b/tests/isolate/illegal_msg_stream_test.dart
@@ -6,6 +6,7 @@
 
 import 'package:expect/expect.dart';
 import 'dart:isolate';
+import '../async_helper.dart';
 
 funcFoo(x) => x + 2;
 
@@ -29,7 +30,9 @@
   snd.add(box.sink);
   snd.close();
 
+  asyncStart();
   box.stream.single.then((msg) {
     Expect.equals(499, msg);
+    asyncEnd();
   });
 }
diff --git a/tests/isolate/illegal_msg_test.dart b/tests/isolate/illegal_msg_test.dart
index 434edc3..aa17b46 100644
--- a/tests/isolate/illegal_msg_test.dart
+++ b/tests/isolate/illegal_msg_test.dart
@@ -5,6 +5,7 @@
 library illegal_msg_tests;
 import "package:expect/expect.dart";
 import 'dart:isolate';
+import '../async_helper.dart';
 
 funcFoo(x) => x + 2;
 
@@ -26,8 +27,10 @@
   if (caught_exception) {
     port.close();
   } else {
+    asyncStart();
     port.receive((msg, reply) {
       print("from worker ${msg}");
+      asyncEnd();
     });
   }
   Expect.isTrue(caught_exception);
diff --git a/tests/isolate/isolate2_negative_test.dart b/tests/isolate/isolate2_negative_test.dart
index 720b825..01cf0ed 100644
--- a/tests/isolate/isolate2_negative_test.dart
+++ b/tests/isolate/isolate2_negative_test.dart
@@ -7,11 +7,16 @@
 
 library isolate2_negative_test;
 import 'dart:isolate';
+import '../async_helper.dart';
 
 void entry() {
   throw "foo";
 }
 
 main() {
+  // We start an asynchronous operation, but since we don't expect to get
+  // anything back except an exception there is no asyncEnd().
+  // If the exception is not thrown this test will timeout.
+  asyncStart();
   SendPort port = spawnFunction(entry);
 }
diff --git a/tests/language/disable_privacy_lib.dart b/tests/language/disable_privacy_lib.dart
deleted file mode 100644
index 6f373b8..0000000
--- a/tests/language/disable_privacy_lib.dart
+++ /dev/null
@@ -1,9 +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.
-//
-// Dart test library checking that library privacy can be disabled.
-
-library DisablePrivacyLib;
-
-var _fooForTesting = 1;
diff --git a/tests/language/disable_privacy_test.dart b/tests/language/disable_privacy_test.dart
deleted file mode 100644
index 6e774e9..0000000
--- a/tests/language/disable_privacy_test.dart
+++ /dev/null
@@ -1,14 +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.
-// VMOptions=--disable_privacy
-//
-// Dart test program checking that library privacy can be disabled.
-
-library DisablePrivacyTest;
-import "package:expect/expect.dart";
-import "disable_privacy_lib.dart";
-
-main() {
-  Expect.equals(1, _fooForTesting);
-}
diff --git a/tests/language/exhaustive_for_test.dart b/tests/language/exhaustive_for_test.dart
new file mode 100644
index 0000000..8aa4cde
--- /dev/null
+++ b/tests/language/exhaustive_for_test.dart
@@ -0,0 +1,808 @@
+// 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.
+// Dart test program for testing for statement.
+
+import "package:expect/expect.dart";
+
+// Test several variations of for loops:
+//   * With or without an initializer.
+//   * With or without a test.
+//   * With or without an update.
+//   * With or without a continue.
+//   * With or without a fall through exit from the body.
+//   * With or without a break.
+
+// Note that some possibilities are infinite loops and so not tested.
+// Combinations that do not have a break or a test but do have a
+// fall through from the body or a continue will never exit the loop.
+
+// Each loop test function sets a status containing a bit for each part of
+// the loop that is present, and then clears the bit as that part of the
+// loop is executed.  The test expectation should be 0 (all present parts
+// were executed), except for a few cases where an update expression is
+// unreachable due to a break or return in the loop body.
+
+const int INIT = 1;
+const int TEST = 2;
+const int UPDATE = 4;
+const int CONTINUE = 8;
+const int FALL = 16;
+const int BREAK = 32;
+
+var status;
+
+void loop0() {
+  status = 0;
+  for(;;) {
+    return;
+  }
+}
+
+void loop1() {
+  status = INIT;
+  for(status &= ~INIT;;) {
+    return;
+  }
+}
+
+void loop2() {
+  status = TEST;
+  for(; (status &= ~TEST) != 0;) {
+    return;
+  }
+}
+
+void loop3() {
+  status = INIT | TEST;
+  for(status &= ~INIT; (status &= ~TEST) != 0;) {
+    return;
+  }
+}
+
+void loop4() {
+  status = UPDATE;
+  for(;; status &= ~UPDATE) {
+    return;
+  }
+}
+
+void loop5() {
+  status = INIT | UPDATE;
+  for(status &= ~INIT;; status &= ~UPDATE) {
+    return;
+  }
+}
+
+void loop6() {
+  status = TEST | UPDATE;
+  for(; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    return;
+  }
+}
+
+void loop7() {
+  status = INIT | TEST | UPDATE;
+  for(status &= ~INIT; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    return;
+  }
+}
+
+// Infinite loop not tested.
+void loop8() {
+  status = CONTINUE;
+  for(;;) {
+    status &= ~CONTINUE;
+    continue;
+  }
+}
+
+// Infinite loop not tested.
+void loop9() {
+  status = INIT | CONTINUE;
+  for(status &= ~INIT;;) {
+    status &= ~CONTINUE;
+    continue;
+  }
+}
+
+void loop10() {
+  status = TEST | CONTINUE;
+  for(; (status &= ~TEST) != 0;) {
+    status &= ~CONTINUE;
+    continue;
+  }
+}
+
+void loop11() {
+  status = INIT | TEST | CONTINUE;
+  for(status &= ~INIT; (status &= ~TEST) != 0;) {
+    status &= ~CONTINUE;
+    continue;
+  }
+}
+
+// Infinite loop.
+void loop12() {
+  status = UPDATE | CONTINUE;
+  for(;; status &= ~UPDATE) {
+    status &= ~CONTINUE;
+    continue;
+  }
+}
+
+// Infinite loop.
+void loop13() {
+  status = INIT | UPDATE | CONTINUE;
+  for(status &= ~INIT;; status &= ~UPDATE) {
+    status &= ~CONTINUE;
+    continue;
+  }
+}
+
+void loop14() {
+  status = TEST | UPDATE | CONTINUE;
+  for(; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    status &= ~CONTINUE;
+    continue;
+  }
+}
+
+void loop15() {
+  status = INIT | TEST | UPDATE | CONTINUE;
+  for(status &= ~INIT; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    status &= ~CONTINUE;
+    continue;
+  }
+}
+
+// Infinite loop.
+void loop16() {
+  status = FALL;
+  for(;;) {
+    status &= ~FALL;
+  }
+}
+
+// Infinite loop.
+void loop17() {
+  status = INIT | FALL;
+  for(status &= ~INIT;;) {
+    status &= ~FALL;
+  }
+}
+
+void loop18() {
+  status = TEST | FALL;
+  for(; (status &= ~TEST) != 0;) {
+    status &= ~FALL;
+  }
+}
+
+void loop19() {
+  status = INIT | TEST | FALL;
+  for(status &= ~INIT; (status &= ~TEST) != 0;) {
+    status &= ~FALL;
+  }
+}
+
+// Infinite loop.
+void loop20() {
+  status = UPDATE | FALL;
+  for(;; status &= ~UPDATE) {
+    status &= ~FALL;
+  }
+}
+
+// Infinite loop.
+void loop21() {
+  status = INIT | UPDATE | FALL;
+  for(status &= ~INIT;; status &= ~UPDATE) {
+    status &= ~FALL;
+  }
+}
+
+void loop22() {
+  status = TEST | UPDATE | FALL;
+  for(; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    status &= ~FALL;
+  }
+}
+
+void loop23() {
+  status = INIT | TEST | UPDATE | FALL;
+  for(status &= ~INIT; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    status &= ~FALL;
+  }
+}
+
+// Infinite loop.
+void loop24() {
+  status = CONTINUE | FALL;
+  for(;;) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~FALL;
+  }
+}
+
+// Infinite loop.
+void loop25() {
+  status = INIT | CONTINUE | FALL;
+  for(status &= ~INIT;;) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~FALL;
+  }
+}
+
+void loop26() {
+  status = TEST | CONTINUE | FALL;
+  for(; (status &= ~TEST) != 0;) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~FALL;
+  }
+}
+
+void loop27() {
+  status = INIT | TEST | CONTINUE | FALL;
+  for(status &= ~INIT; (status &= ~TEST) != 0;) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~FALL;
+  }
+}
+
+// Infinite loop.
+void loop28() {
+  status = UPDATE | CONTINUE | FALL;
+  for(;; status &= ~UPDATE) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~FALL;
+  }
+}
+
+// Infinite loop.
+void loop29() {
+  status = INIT | UPDATE | CONTINUE | FALL;
+  for(status &= ~INIT;; status &= ~UPDATE) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~FALL;
+  }
+}
+
+void loop30() {
+  status = TEST | UPDATE | CONTINUE | FALL;
+  for(; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~FALL;
+  }
+}
+
+void loop31() {
+  status = INIT | TEST | UPDATE | CONTINUE | FALL;
+  for(status &= ~INIT; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~FALL;
+  }
+}
+
+void loop32() {
+  status = BREAK;
+  for(;;) {
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop33() {
+  status = INIT | BREAK;
+  for(status &= ~INIT;;) {
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop34() {
+  status = TEST | BREAK;
+  for(; (status &= ~TEST) != 0;) {
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop35() {
+  status = INIT | TEST | BREAK;
+  for(status &= ~INIT; (status &= ~TEST) != 0;) {
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop36() {
+  status = UPDATE | BREAK;
+  for(;; status &= ~UPDATE) {
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop37() {
+  status = INIT | UPDATE | BREAK;
+  for(status &= ~INIT;; status &= ~UPDATE) {
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop38() {
+  status = TEST | UPDATE | BREAK;
+  for(; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop39() {
+  status = INIT | TEST | UPDATE | BREAK;
+  for(status &= ~INIT; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop40() {
+  status = CONTINUE | BREAK;
+  for(;;) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop41() {
+  status = INIT | CONTINUE | BREAK;
+  for(status &= ~INIT;;) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop42() {
+  status = TEST | CONTINUE | BREAK;
+  for(; (status &= ~TEST) != 0;) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop43() {
+  status = INIT | TEST | CONTINUE | BREAK;
+  for(status &= ~INIT; (status &= ~TEST) != 0;) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop44() {
+  status = UPDATE | CONTINUE | BREAK;
+  for(;; status &= ~UPDATE) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop45() {
+  status = INIT | UPDATE | CONTINUE | BREAK;
+  for(status &= ~INIT;; status &= ~UPDATE) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop46() {
+  status = TEST | UPDATE | CONTINUE | BREAK;
+  for(; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop47() {
+  status = INIT | TEST | UPDATE | CONTINUE | BREAK;
+  for(status &= ~INIT; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    status &= ~BREAK;
+    break;
+  }
+}
+
+void loop48() {
+  status = FALL | BREAK;
+  for(;;) {
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop49() {
+  status = INIT | FALL | BREAK;
+  for(status &= ~INIT;;) {
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop50() {
+  status = TEST | FALL | BREAK;
+  for(; (status &= ~TEST) != 0;) {
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop51() {
+  status = INIT | TEST | FALL | BREAK;
+  for(status &= ~INIT; (status &= ~TEST) != 0;) {
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop52() {
+  status = UPDATE | FALL | BREAK;
+  for(;; status &= ~UPDATE) {
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop53() {
+  status = INIT | UPDATE | FALL | BREAK;
+  for(status &= ~INIT;; status &= ~UPDATE) {
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop54() {
+  status = TEST | UPDATE | FALL | BREAK;
+  for(; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop55() {
+  status = INIT | TEST | UPDATE | FALL | BREAK;
+  for(status &= ~INIT; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop56() {
+  status = CONTINUE | FALL | BREAK;
+  for(;;) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop57() {
+  status = INIT | CONTINUE | FALL | BREAK;
+  for(status &= ~INIT;;) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop58() {
+  status = TEST | CONTINUE | FALL | BREAK;
+  for(; (status &= ~TEST) != 0;) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop59() {
+  status = INIT | TEST | CONTINUE | FALL | BREAK;
+  for(status &= ~INIT; (status &= ~TEST) != 0;) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop60() {
+  status = UPDATE | CONTINUE | FALL | BREAK;
+  for(;; status &= ~UPDATE) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop61() {
+  status = INIT | UPDATE | CONTINUE | FALL | BREAK;
+  for(status &= ~INIT;; status &= ~UPDATE) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop62() {
+  status = TEST | UPDATE | CONTINUE | FALL | BREAK;
+  for(; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void loop63() {
+  status = INIT | TEST | UPDATE | CONTINUE | FALL | BREAK;
+  for(status &= ~INIT; (status &= ~TEST) != 0; status &= ~UPDATE) {
+    if ((status & CONTINUE) == CONTINUE) {
+      status &= ~CONTINUE;
+      continue;
+    }
+    if ((status & FALL) == FALL) {
+      status &= ~FALL;
+    } else {
+      status &= ~BREAK;
+      break;
+    }
+  }
+}
+
+void main() {
+  loop0();
+  Expect.equals(0, status);
+  loop1();
+  Expect.equals(0, status);
+  loop2();
+  Expect.equals(0, status);
+  loop3();
+  Expect.equals(0, status);
+
+  // The next four tests return with status UPDATE because they return
+  // before the update expression is reached.
+  loop4();
+  Expect.equals(UPDATE, status);
+  loop5();
+  Expect.equals(UPDATE, status);
+  loop6();
+  Expect.equals(UPDATE, status);
+  loop7();
+  Expect.equals(UPDATE, status);
+
+  loop10();
+  Expect.equals(0, status);
+  loop11();
+  Expect.equals(0, status);
+  loop14();
+  Expect.equals(0, status);
+  loop15();
+  Expect.equals(0, status);
+  loop18();
+  Expect.equals(0, status);
+  loop19();
+  Expect.equals(0, status);
+  loop22();
+  Expect.equals(0, status);
+  loop23();
+  Expect.equals(0, status);
+  loop26();
+  Expect.equals(0, status);
+  loop27();
+  Expect.equals(0, status);
+  loop30();
+  Expect.equals(0, status);
+  loop31();
+  Expect.equals(0, status);
+  loop32();
+  Expect.equals(0, status);
+  loop33();
+  Expect.equals(0, status);
+  loop34();
+  Expect.equals(0, status);
+  loop35();
+  Expect.equals(0, status);
+
+  // The next four tests return with status UPDATE because they break from
+  // the loop before the update expression is reached.
+  loop36();
+  Expect.equals(4, status);
+  loop37();
+  Expect.equals(4, status);
+  loop38();
+  Expect.equals(4, status);
+  loop39();
+  Expect.equals(4, status);
+
+  loop40();
+  Expect.equals(0, status);
+  loop41();
+  Expect.equals(0, status);
+  loop42();
+  Expect.equals(0, status);
+  loop43();
+  Expect.equals(0, status);
+  loop44();
+  Expect.equals(0, status);
+  loop45();
+  Expect.equals(0, status);
+  loop46();
+  Expect.equals(0, status);
+  loop47();
+  Expect.equals(0, status);
+  loop48();
+  Expect.equals(0, status);
+  loop49();
+  Expect.equals(0, status);
+  loop50();
+  Expect.equals(0, status);
+  loop51();
+  Expect.equals(0, status);
+  loop52();
+  Expect.equals(0, status);
+  loop53();
+  Expect.equals(0, status);
+  loop54();
+  Expect.equals(0, status);
+  loop55();
+  Expect.equals(0, status);
+  loop56();
+  Expect.equals(0, status);
+  loop57();
+  Expect.equals(0, status);
+  loop58();
+  Expect.equals(0, status);
+  loop59();
+  Expect.equals(0, status);
+  loop60();
+  Expect.equals(0, status);
+  loop61();
+  Expect.equals(0, status);
+  loop62();
+  Expect.equals(0, status);
+  loop63();
+  Expect.equals(0, status);
+}
diff --git a/tests/language/function_subtype0_test.dart b/tests/language/function_subtype0_test.dart
new file mode 100644
index 0000000..1a39d92
--- /dev/null
+++ b/tests/language/function_subtype0_test.dart
@@ -0,0 +1,87 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping.
+
+import 'package:expect/expect.dart';
+
+typedef t__();
+typedef void t_void_();
+typedef void t_void_2();
+typedef int t_int_();
+typedef int t_int_2();
+typedef Object t_Object_();
+typedef double t_double_();
+typedef void t_void__int(int i);
+typedef int t_int__int(int i);
+typedef int t_int__int2(int i);
+typedef int t_int__Object(Object o);
+typedef Object t_Object__int(int i);
+typedef int t_int__double(double d);
+typedef int t_int__int_int(int i1, int i2);
+typedef void t_inline_void_(void f());
+typedef void t_inline_void__int(void f(int i));
+
+void _() => null;
+void void_() {}
+void void_2() {}
+int int_() => 0;
+int int_2() => 0;
+Object Object_() => null;
+double double_() => 0.0;
+void void__int(int i) {}
+int int__int(int i) => 0;
+int int__int2(int i) => 0;
+int int__Object(Object o) => 0;
+Object Object__int(int i) => null;
+int int__double(double d) => 0;
+int int__int_int(int i1, int i2) => 0;
+void inline_void_(void f()) {}
+void inline_void__int(void f(int i)) {}
+
+main() {
+  // () -> int <: Function
+  Expect.isTrue(int_ is Function);
+  // () -> dynamic <: () -> dynamic
+  Expect.isTrue(_ is t__);
+  // () -> dynamic <: () -> void
+  Expect.isTrue(_ is t_void_);
+  // () -> void <: () -> dynamic
+  Expect.isTrue(void_ is t__);
+  // () -> int <: () -> void
+  Expect.isTrue(int_ is t_void_);
+  // () -> void <: () -> int
+  Expect.isFalse(void_ is t_int_);
+  // () -> void <: () -> void
+  Expect.isTrue(void_ is t_void_2);
+  // () -> int <: () -> int
+  Expect.isTrue(int_ is t_int_2);
+  // () -> int <: () -> Object
+  Expect.isTrue(int_ is t_Object_);
+  // () -> int <: () -> double
+  Expect.isFalse(int_ is t_double_);
+  // () -> int <: (int) -> void
+  Expect.isFalse(int_ is t_void__int);
+  // () -> void <: (int) -> int
+  Expect.isFalse(void_ is t_int__int);
+  // () -> void <: (int) -> void
+  Expect.isFalse(void_ is t_void__int);
+  // (int) -> int <: (int) -> int
+  Expect.isTrue(int__int is t_int__int2);
+  // (Object) -> int <: (int) -> Object
+  Expect.isTrue(int__Object is t_Object__int);
+  // (int) -> int <: (double) -> int
+  Expect.isFalse(int__int is t_int__double);
+  // () -> int <: (int) -> int
+  Expect.isFalse(int_ is t_int__int);
+  // (int) -> int <: (int,int) -> int
+  Expect.isFalse(int__int is t_int__int_int);
+  // (int,int) -> int <: (int) -> int
+  Expect.isFalse(int__int_int is t_int__int);
+  // (()->void) -> void <: ((int)->void) -> void
+  Expect.isFalse(inline_void_ is t_inline_void__int);
+  // ((int)->void) -> void <: (()->void) -> void
+  Expect.isFalse(inline_void__int is t_inline_void_);
+}
diff --git a/tests/language/function_subtype1_test.dart b/tests/language/function_subtype1_test.dart
new file mode 100644
index 0000000..a7bd199
--- /dev/null
+++ b/tests/language/function_subtype1_test.dart
@@ -0,0 +1,74 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping.
+
+import 'package:expect/expect.dart';
+
+class C<T> {}
+
+typedef _();
+typedef void void_();
+typedef void void_2();
+typedef int int_();
+typedef int int_2();
+typedef Object Object_();
+typedef double double_();
+typedef void void__int(int i);
+typedef int int__int(int i);
+typedef int int__int2(int i);
+typedef int int__Object(Object o);
+typedef Object Object__int(int i);
+typedef int int__double(double d);
+typedef int int__int_int(int i1, int i2);
+typedef void inline_void_(void f());
+typedef void inline_void__int(void f(int i));
+
+main() {
+  // () -> int <: Function
+  Expect.isTrue(new C<int_>() is C<Function>);
+  // Function <: () -> int
+  Expect.isFalse(new C<Function>() is C<int_>);
+  // () -> dynamic <: () -> dynamic
+  Expect.isTrue(new C<_>() is C<_>);
+  // () -> dynamic <: () -> void
+  Expect.isTrue(new C<_>() is C<void_>);
+  // () -> void <: () -> dynamic
+  Expect.isTrue(new C<void_>() is C<_>);
+  // () -> int <: () -> void
+  Expect.isTrue(new C<int_>() is C<void_>);
+  // () -> void <: () -> int
+  Expect.isFalse(new C<void_>() is C<int_>);
+  // () -> void <: () -> void
+  Expect.isTrue(new C<void_>() is C<void_2>);
+  // () -> int <: () -> int
+  Expect.isTrue(new C<int_>() is C<int_2>);
+  // () -> int <: () -> Object
+  Expect.isTrue(new C<int_>() is C<Object_>);
+  // () -> int <: () -> double
+  Expect.isFalse(new C<int_>() is C<double_>);
+  // () -> int <: (int) -> void
+  Expect.isFalse(new C<int_>() is C<void__int>);
+  // () -> void <: (int) -> int
+  Expect.isFalse(new C<void_>() is C<int__int>);
+  // () -> void <: (int) -> void
+  Expect.isFalse(new C<void_>() is C<void__int>);
+  // (int) -> int <: (int) -> int
+  Expect.isTrue(new C<int__int>() is C<int__int2>);
+  // (Object) -> int <: (int) -> Object
+  Expect.isTrue(new C<int__Object>() is C<Object__int>);
+  // (int) -> int <: (double) -> int
+  Expect.isFalse(new C<int__int>() is C<int__double>);
+  // () -> int <: (int) -> int
+  Expect.isFalse(new C<int_>() is C<int__int>);
+  // (int) -> int <: (int,int) -> int
+  Expect.isFalse(new C<int__int>() is C<int__int_int>);
+  // (int,int) -> int <: (int) -> int
+  Expect.isFalse(new C<int__int_int>() is C<int__int>);
+  // (()->void) -> void <: ((int)->void) -> void
+  Expect.isFalse(new C<inline_void_>() is C<inline_void__int>);
+  // ((int)->void) -> void <: (()->void) -> void
+  Expect.isFalse(new C<inline_void__int>() is C<inline_void_>);
+}
diff --git a/tests/language/function_subtype_bound_closure0_test.dart b/tests/language/function_subtype_bound_closure0_test.dart
new file mode 100644
index 0000000..16d36ff
--- /dev/null
+++ b/tests/language/function_subtype_bound_closure0_test.dart
@@ -0,0 +1,40 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for bound closures.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo(bool a, [String b]);
+typedef int Bar(bool a, [String b]);
+typedef int Baz(bool a, {String b});
+typedef int Boz(bool a);
+
+class C {
+  int foo(bool a, [String b]) => null;
+  int baz(bool a, {String b}) => null;
+  int boz(bool a, {int b}) => null;
+}
+
+main() {
+  var c = new C();
+  var foo = c.foo;
+  Expect.isTrue(foo is Foo, 'foo is Foo');
+  Expect.isTrue(foo is Bar, 'foo is Bar');
+  Expect.isFalse(foo is Baz, 'foo is Baz');
+  Expect.isTrue(foo is Boz, 'foo is Boz');
+
+  var baz = c.baz;
+  Expect.isFalse(baz is Foo, 'baz is Foo');
+  Expect.isFalse(baz is Bar, 'baz is Bar');
+  Expect.isTrue(baz is Baz, 'baz is Baz');
+  Expect.isTrue(baz is Boz, 'baz is Boz');
+
+  var boz = c.boz;
+  Expect.isFalse(boz is Foo, 'boz is Foo');
+  Expect.isFalse(boz is Bar, 'boz is Bar');
+  Expect.isFalse(boz is Baz, 'boz is Baz');
+  Expect.isTrue(boz is Boz, 'boz is Boz');
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_bound_closure1_test.dart b/tests/language/function_subtype_bound_closure1_test.dart
new file mode 100644
index 0000000..e3454e2
--- /dev/null
+++ b/tests/language/function_subtype_bound_closure1_test.dart
@@ -0,0 +1,53 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for bound closures against generic typedefs.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo<T>(T a, [String b]);
+typedef int Bar<T>(T a, [String b]);
+typedef int Baz<T>(T a, {String b});
+typedef int Boz<T>(T a);
+
+class C {
+  int foo(bool a, [String b]) => null;
+  int baz(bool a, {String b}) => null;
+}
+
+main() {
+  var c = new C();
+  var foo = c.foo;
+  Expect.isTrue(foo is Foo<bool>, 'foo is Foo<bool>');
+  Expect.isTrue(foo is Bar<bool>, 'foo is Bar<bool>');
+  Expect.isFalse(foo is Baz<bool>, 'foo is Baz<bool>');
+  Expect.isTrue(foo is Boz<bool>, 'foo is Boz<bool>');
+
+  Expect.isFalse(foo is Foo<int>, 'foo is Foo<int>');
+  Expect.isFalse(foo is Bar<int>, 'foo is Bar<int>');
+  Expect.isFalse(foo is Baz<int>, 'foo is Baz<int>');
+  Expect.isFalse(foo is Boz<int>, 'foo is Boz<int>');
+
+  Expect.isTrue(foo is Foo, 'foo is Foo');
+  Expect.isTrue(foo is Bar, 'foo is Bar');
+  Expect.isFalse(foo is Baz, 'foo is Baz');
+  Expect.isTrue(foo is Boz, 'foo is Boz');
+
+  var baz = c.baz;
+  Expect.isFalse(baz is Foo<bool>, 'baz is Foo<bool>');
+  Expect.isFalse(baz is Bar<bool>, 'baz is Bar<bool>');
+  Expect.isTrue(baz is Baz<bool>, 'baz is Baz<bool>');
+  Expect.isTrue(baz is Boz<bool>, 'baz is Boz<bool>');
+
+  Expect.isFalse(baz is Foo<int>, 'baz is Foo<int>');
+  Expect.isFalse(baz is Bar<int>, 'baz is Bar<int>');
+  Expect.isFalse(baz is Baz<int>, 'baz is Baz<int>');
+  Expect.isFalse(baz is Boz<int>, 'baz is Boz<int>');
+
+  Expect.isFalse(baz is Foo, 'baz is Foo');
+  Expect.isFalse(baz is Bar, 'baz is Bar');
+  Expect.isTrue(baz is Baz, 'baz is Baz');
+  Expect.isTrue(baz is Boz, 'baz is Boz');
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_bound_closure2_test.dart b/tests/language/function_subtype_bound_closure2_test.dart
new file mode 100644
index 0000000..9a7da9c
--- /dev/null
+++ b/tests/language/function_subtype_bound_closure2_test.dart
@@ -0,0 +1,40 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for bound closures on generic type against generic
+// typedefs.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo<T>(T a, [String b]);
+typedef int Bar<T>(T a, [String b]);
+typedef int Baz<T>(T a, {String b});
+typedef int Boz<T>(T a);
+typedef int Biz<T>(T a, int b);
+
+class C<T> {
+  int foo(bool a, [String b]) => null;
+  int baz(bool a, {String b}) => null;
+
+  void test(String nameOfT, bool expectedResult) {
+    Expect.equals(expectedResult, foo is Foo<T>, 'foo is Foo<$nameOfT>');
+    Expect.equals(expectedResult, foo is Bar<T>, 'foo is Bar<$nameOfT>');
+    Expect.isFalse(foo is Baz<T>, 'foo is Baz<$nameOfT>');
+    Expect.equals(expectedResult, foo is Boz<T>, 'foo is Boz<$nameOfT>');
+    Expect.isFalse(foo is Biz<T>, 'foo is Biz<$nameOfT>');
+
+    Expect.isFalse(baz is Foo<T>, 'baz is Foo<$nameOfT>');
+    Expect.isFalse(baz is Bar<T>, 'baz is Bar<$nameOfT>');
+    Expect.equals(expectedResult, baz is Baz<T>, 'baz is Baz<$nameOfT>');
+    Expect.equals(expectedResult, baz is Boz<T>, 'baz is Boz<$nameOfT>');
+    Expect.isFalse(baz is Biz<T>, 'bar is Biz<$nameOfT>');
+  }
+}
+
+main() {
+  new C<bool>().test('bool', true);
+  new C<int>().test('int', false);
+  new C().test('dynamic', true);
+}
diff --git a/tests/language/function_subtype_bound_closure3_test.dart b/tests/language/function_subtype_bound_closure3_test.dart
new file mode 100644
index 0000000..1af7b97
--- /dev/null
+++ b/tests/language/function_subtype_bound_closure3_test.dart
@@ -0,0 +1,36 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for generic bound closures.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo(bool a, [String b]);
+typedef void Bar(bool a, [String b]);
+typedef void Baz(bool a, {String b});
+typedef int Boz(bool a);
+
+class C<T> {
+  void foo(T a, [String b]) {}
+  void baz(T a, {String b}) {}
+
+  void test(String nameOfT, bool expectedResult) {
+    Expect.equals(expectedResult, foo is Foo, 'C<$nameOfT>.foo is Foo');
+    Expect.equals(expectedResult, foo is Bar, 'C<$nameOfT>.foo is Bar');
+    Expect.isFalse(foo is Baz, 'C<$nameOfT>.foo is Baz');
+    Expect.isFalse(foo is Boz, 'C<$nameOfT>.foo is Boz');
+
+    Expect.isFalse(baz is Foo, 'C<$nameOfT>.baz is Foo');
+    Expect.isFalse(baz is Bar, 'C<$nameOfT>.baz is Bar');
+    Expect.equals(expectedResult, baz is Baz, 'C<$nameOfT>.baz is Baz');
+    Expect.isFalse(baz is Boz, 'C<$nameOfT>.baz is Boz');
+  }
+}
+
+main() {
+  new C<bool>().test('bool', true);
+  new C<int>().test('int', false);
+  new C().test('dynamic', true);
+}
diff --git a/tests/language/function_subtype_bound_closure4_test.dart b/tests/language/function_subtype_bound_closure4_test.dart
new file mode 100644
index 0000000..99cd743
--- /dev/null
+++ b/tests/language/function_subtype_bound_closure4_test.dart
@@ -0,0 +1,38 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for generic bound closures.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo(bool a, [String b]);
+typedef void Bar(bool a, [String b]);
+typedef void Baz(bool a, {String b});
+typedef int Boz(bool a);
+
+class C<T> {
+  void foo(T a, [String b]) {}
+  void baz(T a, {String b}) {}
+
+  void test(String nameOfT, bool expectedResult) {
+    Expect.equals(expectedResult, foo is Foo, 'C<$nameOfT>.foo is Foo');
+    Expect.equals(expectedResult, foo is Bar, 'C<$nameOfT>.foo is Bar');
+    Expect.isFalse(foo is Baz, 'C<$nameOfT>.foo is Baz');
+    Expect.isFalse(foo is Boz, 'C<$nameOfT>.foo is Boz');
+
+    Expect.isFalse(baz is Foo, 'C<$nameOfT>.baz is Foo');
+    Expect.isFalse(baz is Bar, 'C<$nameOfT>.baz is Bar');
+    Expect.equals(expectedResult, baz is Baz, 'C<$nameOfT>.baz is Baz');
+    Expect.isFalse(baz is Boz, 'C<$nameOfT>.baz is Boz');
+  }
+}
+
+class D<S, T> extends C<T> {}
+
+main() {
+  new D<String, bool>().test('bool', true);
+  new D<bool, int>().test('int', false);
+  new D().test('dynamic', true);
+}
diff --git a/tests/language/function_subtype_bound_closure5_test.dart b/tests/language/function_subtype_bound_closure5_test.dart
new file mode 100644
index 0000000..8192b6f
--- /dev/null
+++ b/tests/language/function_subtype_bound_closure5_test.dart
@@ -0,0 +1,42 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for bound closures on generic type against generic
+// typedefs.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo<T>(T a, [String b]);
+typedef int Bar<T>(T a, [String b]);
+typedef int Baz<T>(T a, {String b});
+typedef int Boz<T>(T a);
+typedef int Biz<T>(T a, int b);
+
+class C<T> {
+  int foo(bool a, [String b]) => null;
+  int baz(bool a, {String b}) => null;
+
+  void test(String nameOfT, bool expectedResult) {
+    Expect.equals(expectedResult, foo is Foo<T>, 'foo is Foo<$nameOfT>');
+    Expect.equals(expectedResult, foo is Bar<T>, 'foo is Bar<$nameOfT>');
+    Expect.isFalse(foo is Baz<T>, 'foo is Baz<$nameOfT>');
+    Expect.equals(expectedResult, foo is Boz<T>, 'foo is Boz<$nameOfT>');
+    Expect.isFalse(foo is Biz<T>, 'foo is Biz<$nameOfT>');
+
+    Expect.isFalse(baz is Foo<T>, 'baz is Foo<$nameOfT>');
+    Expect.isFalse(baz is Bar<T>, 'baz is Bar<$nameOfT>');
+    Expect.equals(expectedResult, baz is Baz<T>, 'baz is Baz<$nameOfT>');
+    Expect.equals(expectedResult, baz is Boz<T>, 'baz is Boz<$nameOfT>');
+    Expect.isFalse(baz is Biz<T>, 'bar is Biz<$nameOfT>');
+  }
+}
+
+class D<S, T> extends C<T> {}
+
+main() {
+  new D<String, bool>().test('bool', true);
+  new D<bool, int>().test('int', false);
+  new D().test('dynamic', true);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_bound_closure6_test.dart b/tests/language/function_subtype_bound_closure6_test.dart
new file mode 100644
index 0000000..931e458
--- /dev/null
+++ b/tests/language/function_subtype_bound_closure6_test.dart
@@ -0,0 +1,43 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for bound closures on generic type against generic
+// typedefs.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo<T>(T a, [String b]);
+typedef int Bar<T>(T a, [String b]);
+typedef int Baz<T>(T a, {String b});
+typedef int Boz<T>(T a);
+typedef int Biz<T>(T a, int b);
+
+class C<T> {
+  int foo(bool a, [String b]) => null;
+  int baz(bool a, {String b}) => null;
+
+  void test(String nameOfT, bool expectedResult) {
+    void localMethod() {
+      Expect.equals(expectedResult, foo is Foo<T>, 'foo is Foo<$nameOfT>');
+      Expect.equals(expectedResult, foo is Bar<T>, 'foo is Bar<$nameOfT>');
+      Expect.isFalse(foo is Baz<T>, 'foo is Baz<$nameOfT>');
+      Expect.equals(expectedResult, foo is Boz<T>, 'foo is Boz<$nameOfT>');
+      Expect.isFalse(foo is Biz<T>, 'foo is Biz<$nameOfT>');
+
+      Expect.isFalse(baz is Foo<T>, 'baz is Foo<$nameOfT>');
+      Expect.isFalse(baz is Bar<T>, 'baz is Bar<$nameOfT>');
+      Expect.equals(expectedResult, baz is Baz<T>, 'baz is Baz<$nameOfT>');
+      Expect.equals(expectedResult, baz is Boz<T>, 'baz is Boz<$nameOfT>');
+      Expect.isFalse(baz is Biz<T>, 'bar is Biz<$nameOfT>');
+    }
+    localMethod();
+  }
+}
+
+main() {
+  new C<bool>().test('bool', true);
+  new C<int>().test('int', false);
+  new C().test('dynamic', true);
+}
diff --git a/tests/language/function_subtype_bound_closure7_test.dart b/tests/language/function_subtype_bound_closure7_test.dart
new file mode 100644
index 0000000..5f24aa9
--- /dev/null
+++ b/tests/language/function_subtype_bound_closure7_test.dart
@@ -0,0 +1,33 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for bound closures.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo<T>(T t);
+
+class Class<T> {
+  foo(Foo<T> o) => o is Foo<T>;
+}
+
+void bar(int i) {}
+
+void main() {
+  bool inCheckedMode = false;
+  try {
+    String a = 42;
+  } catch (e) {
+    inCheckedMode = true;
+  }
+
+  var f = new Class<int>().foo;
+  Expect.isTrue(f(bar));
+  if (inCheckedMode) {
+    Expect.throws(() => f(f), (e) => true);
+  } else {
+    Expect.isFalse(f(f));
+  }
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_call0_test.dart b/tests/language/function_subtype_call0_test.dart
new file mode 100644
index 0000000..d862683
--- /dev/null
+++ b/tests/language/function_subtype_call0_test.dart
@@ -0,0 +1,42 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for classes with call functions.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo(bool a, [String b]);
+typedef void Bar(bool a, [String b]);
+typedef void Baz(bool a, {String b});
+typedef void Boz(bool a);
+
+class C1 {
+  void call(bool a, [String b]) {}
+}
+
+class C2 {
+  void call(bool a, {String b}) {}
+}
+
+class C3 {
+  void call(bool a, {int b}) {}
+}
+
+main() {
+  Expect.isTrue(new C1() is Foo, 'new C1() is Foo');
+  Expect.isTrue(new C1() is Bar, 'new C1() is Bar');
+  Expect.isFalse(new C1() is Baz, 'new C1() is Baz');
+  Expect.isTrue(new C1() is Boz, 'new C1() is Boz');
+
+  Expect.isFalse(new C2() is Foo, 'new C2() is Foo');
+  Expect.isFalse(new C2() is Bar, 'new C2() is Bar');
+  Expect.isTrue(new C2() is Baz, 'new C2() is Baz');
+  Expect.isTrue(new C2() is Boz, 'new C2() is Boz');
+
+  Expect.isFalse(new C3() is Foo, 'new C3() is Foo');
+  Expect.isFalse(new C3() is Bar, 'new C3() is Bar');
+  Expect.isFalse(new C3() is Baz, 'new C3() is Baz');
+  Expect.isTrue(new C3() is Boz, 'new C3() is Boz');
+}
diff --git a/tests/language/function_subtype_call1_test.dart b/tests/language/function_subtype_call1_test.dart
new file mode 100644
index 0000000..2ac5e43
--- /dev/null
+++ b/tests/language/function_subtype_call1_test.dart
@@ -0,0 +1,53 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for classes with call functions.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo(bool a, [String b]);
+typedef void Bar(bool a, [String b]);
+typedef void Baz(bool a, {String b});
+typedef void Boz(bool a);
+
+class C1<T> {
+  void call(T a, [String b]) {}
+}
+
+class C2<T> {
+  void call(T a, {String b}) {}
+}
+
+main() {
+  Expect.isTrue(new C1<bool>() is Foo, 'new C1<bool>() is Foo');
+  Expect.isTrue(new C1<bool>() is Bar, 'new C1<bool>() is Bar');
+  Expect.isFalse(new C1<bool>() is Baz, 'new C1<bool>() is Baz');
+  Expect.isTrue(new C1<bool>() is Boz, 'new C1<bool>() is Boz');
+
+  Expect.isFalse(new C1<int>() is Foo, 'new C1<int>() is Foo');
+  Expect.isFalse(new C1<int>() is Bar, 'new C1<int>() is Bar');
+  Expect.isFalse(new C1<int>() is Baz, 'new C1<int>() is Baz');
+  Expect.isFalse(new C1<int>() is Boz, 'new C1<int>() is Boz');
+
+  Expect.isTrue(new C1() is Foo, 'new C1() is Foo');
+  Expect.isTrue(new C1() is Bar, 'new C1() is Bar');
+  Expect.isFalse(new C1() is Baz, 'new C1() is Baz');
+  Expect.isTrue(new C1() is Boz, 'new C1() is Boz');
+
+  Expect.isFalse(new C2<bool>() is Foo, 'new C2<bool>() is Foo');
+  Expect.isFalse(new C2<bool>() is Bar, 'new C2<bool>() is Bar');
+  Expect.isTrue(new C2<bool>() is Baz, 'new C2<bool>() is Baz');
+  Expect.isTrue(new C2<bool>() is Boz, 'new C2<bool>() is Boz');
+
+  Expect.isFalse(new C2<int>() is Foo, 'new C2<int>() is Foo');
+  Expect.isFalse(new C2<int>() is Bar, 'new C2<int>() is Bar');
+  Expect.isFalse(new C2<int>() is Baz, 'new C2<int>() is Baz');
+  Expect.isFalse(new C2<int>() is Boz, 'new C2<int>() is Boz');
+
+  Expect.isFalse(new C2() is Foo, 'new C2() is Foo');
+  Expect.isFalse(new C2() is Bar, 'new C2() is Bar');
+  Expect.isTrue(new C2() is Baz, 'new C2() is Baz');
+  Expect.isTrue(new C2() is Boz, 'new C2() is Boz');
+}
diff --git a/tests/language/function_subtype_call2_test.dart b/tests/language/function_subtype_call2_test.dart
new file mode 100644
index 0000000..8dabe8f
--- /dev/null
+++ b/tests/language/function_subtype_call2_test.dart
@@ -0,0 +1,60 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for classes with call functions.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo(bool a, [String b]);
+typedef void Bar(bool a, [String b]);
+typedef void Baz(bool a, {String b});
+typedef void Boz(bool a);
+
+class C1<T> {
+  void call(T a, [String b]) {}
+}
+
+class D1<S, T> extends C1<T> {}
+
+class C2<T> {
+  void call(T a, {String b}) {}
+}
+
+class D2<S, T> extends C2<T> {}
+
+main() {
+  Expect.isTrue(new D1<String, bool>() is Foo, 'new D1<String, bool>() is Foo');
+  Expect.isTrue(new D1<String, bool>() is Bar, 'new D1<String, bool>() is Bar');
+  Expect.isFalse(new D1<String, bool>() is Baz,
+                 'new D1<String, bool>() is Baz');
+  Expect.isTrue(new D1<String, bool>() is Boz, 'new D1<String, bool>() is Boz');
+
+  Expect.isFalse(new D1<bool, int>() is Foo, 'new D1<bool, int>() is Foo');
+  Expect.isFalse(new D1<bool, int>() is Bar, 'new D1<bool, int>() is Bar');
+  Expect.isFalse(new D1<bool, int>() is Baz, 'new D1<bool, int>() is Baz');
+  Expect.isFalse(new D1<bool, int>() is Boz, 'new D1<bool, int>() is Boz');
+
+  Expect.isTrue(new D1() is Foo, 'new D1() is Foo');
+  Expect.isTrue(new D1() is Bar, 'new D1() is Bar');
+  Expect.isFalse(new D1() is Baz, 'new D1() is Baz');
+  Expect.isTrue(new D1() is Boz, 'new D1() is Boz');
+
+  Expect.isFalse(new D2<String, bool>() is Foo,
+                 'new D2<String, bool>() is Foo');
+  Expect.isFalse(new D2<String, bool>() is Bar,
+                 'new D2<String, bool>() is Bar');
+  Expect.isTrue(new D2<String, bool>() is Baz, 'new D2<String, bool>() is Baz');
+  Expect.isTrue(new D2<String, bool>() is Boz, 'new D2<String, bool>() is Boz');
+
+  Expect.isFalse(new D2<bool, int>() is Foo, 'new D2<bool, int>() is Foo');
+  Expect.isFalse(new D2<bool, int>() is Bar, 'new D2<bool, int>() is Bar');
+  Expect.isFalse(new D2<bool, int>() is Baz, 'new D2<bool, int>() is Baz');
+  Expect.isFalse(new D2<bool, int>() is Boz, 'new D2<bool, int>() is Boz');
+
+  Expect.isFalse(new D2() is Foo, 'new D2() is Foo');
+  Expect.isFalse(new D2() is Bar, 'new D2() is Bar');
+  Expect.isTrue(new D2() is Baz, 'new D2() is Baz');
+  Expect.isTrue(new D2() is Boz, 'new D2() is Boz');
+}
diff --git a/tests/language/function_subtype_cast0_test.dart b/tests/language/function_subtype_cast0_test.dart
new file mode 100644
index 0000000..455d32b
--- /dev/null
+++ b/tests/language/function_subtype_cast0_test.dart
@@ -0,0 +1,20 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping casts.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo<T>(T t);
+typedef void Bar(int i);
+
+void bar(int i) {}
+
+void main() {
+  Expect.isNotNull(bar as Foo);
+  Expect.throws(() => bar as Foo<bool>, (e) => true);
+  Expect.isNotNull(bar as Foo<int>);
+  Expect.isNotNull(bar as Bar);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_cast1_test.dart b/tests/language/function_subtype_cast1_test.dart
new file mode 100644
index 0000000..74b694a
--- /dev/null
+++ b/tests/language/function_subtype_cast1_test.dart
@@ -0,0 +1,32 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping casts.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo<T>(T t);
+typedef void Bar(int i);
+
+class Class<T> {
+  void bar(T i) {}
+}
+
+void main() {
+  Expect.isNotNull(new Class().bar as Foo);
+  Expect.isNotNull(new Class().bar as Foo<bool>);
+  Expect.isNotNull(new Class().bar as Foo<int>);
+  Expect.isNotNull(new Class().bar as Bar);
+
+  Expect.isNotNull(new Class<int>().bar as Foo);
+  Expect.throws(() => new Class<int>().bar as Foo<bool>, (e) => true);
+  Expect.isNotNull(new Class<int>().bar as Foo<int>);
+  Expect.isNotNull(new Class<int>().bar as Bar);
+
+  Expect.isNotNull(new Class<bool>().bar as Foo);
+  Expect.isNotNull(new Class<bool>().bar as Foo<bool>);
+  Expect.throws(() => new Class<bool>().bar as Foo<int>, (e) => true);
+  Expect.throws(() => new Class<bool>().bar as Bar, (e) => true);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_cast2_test.dart b/tests/language/function_subtype_cast2_test.dart
new file mode 100644
index 0000000..3f1aaa6
--- /dev/null
+++ b/tests/language/function_subtype_cast2_test.dart
@@ -0,0 +1,30 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping casts.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo<T>(T t);
+typedef void Bar(int i);
+
+class Class<T> {
+  test(bool expectedResult, var o, String typeName) {
+    if (expectedResult) {
+      Expect.isNotNull(o as Foo<T>, "bar as Foo<$typeName>");
+    } else {
+      Expect.throws(() => o as Foo<T>, (e) => true, "bar as Foo<$typeName>");
+    }
+    Expect.isNotNull(o as Bar, "bar as Bar");
+  }
+}
+
+void bar(int i) {}
+
+void main() {
+  new Class().test(true, bar, "dynamic");
+  new Class<int>().test(true, bar, "int");
+  new Class<bool>().test(false, bar, "bool");
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_cast3_test.dart b/tests/language/function_subtype_cast3_test.dart
new file mode 100644
index 0000000..ba6f4ac
--- /dev/null
+++ b/tests/language/function_subtype_cast3_test.dart
@@ -0,0 +1,33 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping casts.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo<T>(T t);
+typedef void Bar(int i);
+
+class Class<T> {
+  test(bool expectedResult, var o, String typeName) {
+    void local() {
+      if (expectedResult) {
+        Expect.isNotNull(o as Foo<T>, "bar as Foo<$typeName>");
+      } else {
+        Expect.throws(() => o as Foo<T>, (e) => true, "bar as Foo<$typeName>");
+      }
+      Expect.isNotNull(o as Bar, "bar as Bar");
+    }
+    local();
+  }
+}
+
+void bar(int i) {}
+
+void main() {
+  new Class().test(true, bar, "dynamic");
+  new Class<int>().test(true, bar, "int");
+  new Class<bool>().test(false, bar, "bool");
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_checked0_test.dart b/tests/language/function_subtype_checked0_test.dart
new file mode 100644
index 0000000..ee293d6
--- /dev/null
+++ b/tests/language/function_subtype_checked0_test.dart
@@ -0,0 +1,79 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping of typedef vs. inlined function types.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo<T>(T a, [String b]);
+typedef int Bar<T>(T a, [String b]);
+typedef int Baz<T>(T a, {String b});
+typedef int Boz<T>(T a);
+
+int foo(bool a, [String b]) => null;
+int baz(bool a, {String b}) => null;
+int boz(bool a, {int b}) => null;
+
+class C<T> {
+  void test1a(Foo<T> f) {}
+  void test1b(Bar<T> f) {}
+  void test1c(int f(T a, [String b])) {}
+
+  void test2a(Baz<T> f) {}
+  void test2b(int f(T a, {String b})) {}
+
+  void test3a(Boz<T> f) {}
+  void test3b(int f(T a)) {}
+
+  void test(String nameOfT, bool expectedResult) {
+    check(bool expectedResult, f()) {
+      if (inCheckedMode() && !expectedResult) {
+        Expect.throws(f, (e) => true);
+      } else {
+        f();
+      }
+    }
+
+    check(expectedResult, () => test1a(foo));
+    check(expectedResult, () => test1b(foo));
+    check(expectedResult, () => test1b(foo));
+    check(false, () => test2a(foo));
+    check(false, () => test2b(foo));
+    check(expectedResult, () => test3a(foo));
+    check(expectedResult, () => test3b(foo));
+
+    check(false, () => test1a(baz));
+    check(false, () => test1b(baz));
+    check(false, () => test1b(baz));
+    check(expectedResult, () => test2a(baz));
+    check(expectedResult, () => test2b(baz));
+    check(expectedResult, () => test3a(baz));
+    check(expectedResult, () => test3b(baz));
+
+    check(false, () => test1a(boz));
+    check(false, () => test1b(boz));
+    check(false, () => test1b(boz));
+    check(false, () => test2a(boz));
+    check(false, () => test2b(boz));
+    check(expectedResult, () => test3a(boz));
+    check(expectedResult, () => test3b(boz));
+  }
+}
+
+main() {
+  new C<bool>().test('bool', true);
+  new C<int>().test('int', false);
+  new C().test('dynamic', true);
+}
+
+bool inCheckedMode() {
+  try {
+    var x = 42;
+    String a = x;
+  } catch (e) {
+    return true;
+  }
+  return false;
+}
diff --git a/tests/language/function_subtype_closure0_test.dart b/tests/language/function_subtype_closure0_test.dart
new file mode 100644
index 0000000..1d6437b
--- /dev/null
+++ b/tests/language/function_subtype_closure0_test.dart
@@ -0,0 +1,36 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping of static functions.
+
+import 'package:expect/expect.dart';
+
+typedef I<T> f2<T>();
+
+class X {
+  static J<bool> f1() => null;
+}
+
+class C<T> {
+  C(f2<T> f);
+}
+
+class I<T> {}
+class J<T> extends I<int> {}
+
+main() {
+
+  bool inCheckedMode = false;
+  try {
+    String a = 42;
+  } catch (e) {
+    inCheckedMode = true;
+  }
+
+  new C<int>(X.f1);
+  if (inCheckedMode) {
+    Expect.throws(() => new C<bool>(X.f1), (e) => true);
+  }
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_closure1_test.dart b/tests/language/function_subtype_closure1_test.dart
new file mode 100644
index 0000000..5c62341
--- /dev/null
+++ b/tests/language/function_subtype_closure1_test.dart
@@ -0,0 +1,35 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping of dynamic closures.
+
+import 'package:expect/expect.dart';
+
+typedef I<T> f2<T>();
+
+class X {
+  J<bool> f1() => null;
+}
+
+class C<T> {
+  C(f2<T> f);
+}
+
+class I<T> {}
+class J<T> extends I<int> {}
+
+main() {
+  bool inCheckedMode = false;
+  try {
+    String a = 42;
+  } catch (e) {
+    inCheckedMode = true;
+  }
+
+  new C<int>(new X().f1);
+  if (inCheckedMode) {
+    Expect.throws(() => new C<bool>(new X().f1), (e) => true);
+  }
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_factory0_test.dart b/tests/language/function_subtype_factory0_test.dart
new file mode 100644
index 0000000..91d6056
--- /dev/null
+++ b/tests/language/function_subtype_factory0_test.dart
@@ -0,0 +1,27 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping with type variables in factory constructors.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo<T>(T t);
+
+class C<T> {
+  factory C(foo) {
+    if (foo is Foo<T>) {
+      return new C.internal();
+    }
+    return null;
+  }
+  C.internal();
+}
+
+void method(String s) {}
+
+void main() {
+  Expect.isNotNull(new C<String>(method));
+  Expect.isNull(new C<bool>(method));
+}
diff --git a/tests/language/function_subtype_factory1_test.dart b/tests/language/function_subtype_factory1_test.dart
new file mode 100644
index 0000000..2ad4d35
--- /dev/null
+++ b/tests/language/function_subtype_factory1_test.dart
@@ -0,0 +1,35 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping with type variables in factory constructors.
+
+import 'package:expect/expect.dart';
+
+class C<T> {
+  factory C(void foo(T t)) => new C.internal();
+  C.internal();
+}
+
+void method(String s) {}
+
+void main() {
+  Expect.isNotNull(new C<String>(method));
+  try {
+    new C<bool>(method);
+    Expect.isFalse(isCheckedMode());
+  } catch (e) {
+    Expect.isTrue(isCheckedMode());
+  }
+}
+
+isCheckedMode() {
+  try {
+    var i = 1;
+    String s = i;
+    return false;
+  } catch (e) {
+    return true;
+  }
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_inline0_test.dart b/tests/language/function_subtype_inline0_test.dart
new file mode 100644
index 0000000..40b49ef
--- /dev/null
+++ b/tests/language/function_subtype_inline0_test.dart
@@ -0,0 +1,41 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for generic bound closures.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo(bool a, [String b]);
+typedef void Bar(bool a, [String b]);
+typedef void Baz(bool a, {String b});
+typedef int Boz(bool a);
+
+class C<T> {
+  void test(String nameOfT, bool expectedResult) {
+    Expect.equals(expectedResult, (T a, [String b]) {} is Foo,
+        '($nameOfT,[String])->void is Foo');
+    Expect.equals(expectedResult, (T a, [String b]) {} is Bar,
+        '($nameOfT,[String])->void is Bar');
+    Expect.isFalse((T a, [String b]) {} is Baz,
+        '($nameOfT,[String])->void is Baz');
+    Expect.equals(expectedResult, (T a, [String b]) {} is Boz,
+        '($nameOfT,[String])->void is Boz');
+
+    Expect.isFalse((T a, {String b}) {} is Foo,
+        '($nameOfT,{b:String})->void is Foo');
+    Expect.isFalse((T a, {String b}) {} is Bar,
+        '($nameOfT,{b:String})->void is Bar');
+    Expect.equals(expectedResult, (T a, {String b}) {} is Baz,
+        '($nameOfT,{b:String})->void is Baz');
+    Expect.equals(expectedResult, (T a, {String b}) {} is Boz,
+        '($nameOfT,{b:String})->void is Boz');
+  }
+}
+
+main() {
+  new C<bool>().test('bool', true);
+  new C<int>().test('int', false);
+  new C().test('dynamic', true);
+}
diff --git a/tests/language/function_subtype_inline1_test.dart b/tests/language/function_subtype_inline1_test.dart
new file mode 100644
index 0000000..74491db
--- /dev/null
+++ b/tests/language/function_subtype_inline1_test.dart
@@ -0,0 +1,39 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping.
+
+import 'package:expect/expect.dart';
+
+class A {}
+class B extends A {}
+class C extends A {}
+
+class Class<K,V> {
+  void forEach(void f(K k, V v)) {}
+}
+
+main() {
+  Class<B,C> c = new Class<B,C>();
+  c.forEach((A a, A b) {});
+  c.forEach((B a, C b) {});
+  try {
+    c.forEach((A a, B b) {});
+    Expect.isFalse(isCheckedMode());
+  } catch (e) {
+    Expect.isTrue(isCheckedMode());
+  }
+}
+
+
+isCheckedMode() {
+  try {
+    var i = 1;
+    String s = i;
+    return false;
+  } catch (e) {
+    return true;
+  }
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_local0_test.dart b/tests/language/function_subtype_local0_test.dart
new file mode 100644
index 0000000..bec28d3
--- /dev/null
+++ b/tests/language/function_subtype_local0_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for local functions.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo(bool a, [String b]);
+typedef int Bar(bool a, [String b]);
+typedef int Baz(bool a, {String b});
+typedef int Boz(bool a);
+
+main() {
+  int foo(bool a, [String b]) => null;
+  int baz(bool a, {String b}) => null;
+  int boz(bool a, {int b}) => null;
+
+  Expect.isTrue(foo is Foo, 'foo is Foo');
+  Expect.isTrue(foo is Bar, 'foo is Bar');
+  Expect.isFalse(foo is Baz, 'foo is Baz');
+  Expect.isTrue(foo is Boz, 'foo is Boz');
+
+  Expect.isFalse(baz is Foo, 'baz is Foo');
+  Expect.isFalse(baz is Bar, 'baz is Bar');
+  Expect.isTrue(baz is Baz, 'baz is Baz');
+  Expect.isTrue(baz is Boz, 'baz is Boz');
+
+  Expect.isFalse(boz is Foo, 'boz is Foo');
+  Expect.isFalse(boz is Bar, 'boz is Bar');
+  Expect.isFalse(boz is Baz, 'boz is Baz');
+  Expect.isTrue(boz is Boz, 'boz is Boz');
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_local1_test.dart b/tests/language/function_subtype_local1_test.dart
new file mode 100644
index 0000000..f2755f7
--- /dev/null
+++ b/tests/language/function_subtype_local1_test.dart
@@ -0,0 +1,48 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for local functions against generic typedefs.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo<T>(T a, [String b]);
+typedef int Bar<T>(T a, [String b]);
+typedef int Baz<T>(T a, {String b});
+typedef int Boz<T>(T a);
+
+main() {
+  int foo(bool a, [String b]) => null;
+  int baz(bool a, {String b}) => null;
+
+  Expect.isTrue(foo is Foo<bool>, 'foo is Foo<bool>');
+  Expect.isTrue(foo is Bar<bool>, 'foo is Bar<bool>');
+  Expect.isFalse(foo is Baz<bool>, 'foo is Baz<bool>');
+  Expect.isTrue(foo is Boz<bool>, 'foo is Boz<bool>');
+
+  Expect.isFalse(foo is Foo<int>, 'foo is Foo<int>');
+  Expect.isFalse(foo is Bar<int>, 'foo is Bar<int>');
+  Expect.isFalse(foo is Baz<int>, 'foo is Baz<int>');
+  Expect.isFalse(foo is Boz<int>, 'foo is Boz<int>');
+
+  Expect.isTrue(foo is Foo, 'foo is Foo');
+  Expect.isTrue(foo is Bar, 'foo is Bar');
+  Expect.isFalse(foo is Baz, 'foo is Baz');
+  Expect.isTrue(foo is Boz, 'foo is Boz');
+
+  Expect.isFalse(baz is Foo<bool>, 'baz is Foo<bool>');
+  Expect.isFalse(baz is Bar<bool>, 'baz is Bar<bool>');
+  Expect.isTrue(baz is Baz<bool>, 'baz is Baz<bool>');
+  Expect.isTrue(baz is Boz<bool>, 'baz is Boz<bool>');
+
+  Expect.isFalse(baz is Foo<int>, 'baz is Foo<int>');
+  Expect.isFalse(baz is Bar<int>, 'baz is Bar<int>');
+  Expect.isFalse(baz is Baz<int>, 'baz is Baz<int>');
+  Expect.isFalse(baz is Boz<int>, 'baz is Boz<int>');
+
+  Expect.isFalse(baz is Foo, 'baz is Foo');
+  Expect.isFalse(baz is Bar, 'baz is Bar');
+  Expect.isTrue(baz is Baz, 'baz is Baz');
+  Expect.isTrue(baz is Boz, 'baz is Boz');
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_local2_test.dart b/tests/language/function_subtype_local2_test.dart
new file mode 100644
index 0000000..65d470d
--- /dev/null
+++ b/tests/language/function_subtype_local2_test.dart
@@ -0,0 +1,40 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for local functions on generic type against generic
+// typedefs.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo<T>(T a, [String b]);
+typedef int Bar<T>(T a, [String b]);
+typedef int Baz<T>(T a, {String b});
+typedef int Boz<T>(T a);
+typedef int Biz<T>(T a, int b);
+
+class C<T> {
+  void test(String nameOfT, bool expectedResult) {
+    int foo(bool a, [String b]) => null;
+    int baz(bool a, {String b}) => null;
+
+    Expect.equals(expectedResult, foo is Foo<T>, 'foo is Foo<$nameOfT>');
+    Expect.equals(expectedResult, foo is Bar<T>, 'foo is Bar<$nameOfT>');
+    Expect.isFalse(foo is Baz<T>, 'foo is Baz<$nameOfT>');
+    Expect.equals(expectedResult, foo is Boz<T>, 'foo is Boz<$nameOfT>');
+    Expect.isFalse(foo is Biz<T>, 'foo is Biz<$nameOfT>');
+
+    Expect.isFalse(baz is Foo<T>, 'baz is Foo<$nameOfT>');
+    Expect.isFalse(baz is Bar<T>, 'baz is Bar<$nameOfT>');
+    Expect.equals(expectedResult, baz is Baz<T>, 'baz is Baz<$nameOfT>');
+    Expect.equals(expectedResult, baz is Boz<T>, 'baz is Boz<$nameOfT>');
+    Expect.isFalse(baz is Biz<T>, 'bar is Biz<$nameOfT>');
+  }
+}
+
+main() {
+  new C<bool>().test('bool', true);
+  new C<int>().test('int', false);
+  new C().test('dynamic', true);
+}
diff --git a/tests/language/function_subtype_local3_test.dart b/tests/language/function_subtype_local3_test.dart
new file mode 100644
index 0000000..344f7c2
--- /dev/null
+++ b/tests/language/function_subtype_local3_test.dart
@@ -0,0 +1,36 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for generic bound closures.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo(bool a, [String b]);
+typedef void Bar(bool a, [String b]);
+typedef void Baz(bool a, {String b});
+typedef int Boz(bool a);
+
+class C<T> {
+  void test(String nameOfT, bool expectedResult) {
+    void foo(T a, [String b]) {}
+    void baz(T a, {String b}) {}
+
+    Expect.equals(expectedResult, foo is Foo, 'C<$nameOfT>.foo is Foo');
+    Expect.equals(expectedResult, foo is Bar, 'C<$nameOfT>.foo is Bar');
+    Expect.isFalse(foo is Baz, 'C<$nameOfT>.foo is Baz');
+    Expect.isFalse(foo is Boz, 'C<$nameOfT>.foo is Boz');
+
+    Expect.isFalse(baz is Foo, 'C<$nameOfT>.baz is Foo');
+    Expect.isFalse(baz is Bar, 'C<$nameOfT>.baz is Bar');
+    Expect.equals(expectedResult, baz is Baz, 'C<$nameOfT>.baz is Baz');
+    Expect.isFalse(baz is Boz, 'C<$nameOfT>.baz is Boz');
+  }
+}
+
+main() {
+  new C<bool>().test('bool', true);
+  new C<int>().test('int', false);
+  new C().test('dynamic', true);
+}
diff --git a/tests/language/function_subtype_local4_test.dart b/tests/language/function_subtype_local4_test.dart
new file mode 100644
index 0000000..5219757
--- /dev/null
+++ b/tests/language/function_subtype_local4_test.dart
@@ -0,0 +1,39 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for generic bound closures. This also tests
+// type argument substitution.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo(bool a, [String b]);
+typedef void Bar(bool a, [String b]);
+typedef void Baz(bool a, {String b});
+typedef int Boz(bool a);
+
+class C<T> {
+  void test(String nameOfT, bool expectedResult) {
+    void foo(T a, [String b]) {}
+    void baz(T a, {String b}) {}
+
+    Expect.equals(expectedResult, foo is Foo, 'C<$nameOfT>.foo is Foo');
+    Expect.equals(expectedResult, foo is Bar, 'C<$nameOfT>.foo is Bar');
+    Expect.isFalse(foo is Baz, 'C<$nameOfT>.foo is Baz');
+    Expect.isFalse(foo is Boz, 'C<$nameOfT>.foo is Boz');
+
+    Expect.isFalse(baz is Foo, 'C<$nameOfT>.baz is Foo');
+    Expect.isFalse(baz is Bar, 'C<$nameOfT>.baz is Bar');
+    Expect.equals(expectedResult, baz is Baz, 'C<$nameOfT>.baz is Baz');
+    Expect.isFalse(baz is Boz, 'C<$nameOfT>.baz is Boz');
+  }
+}
+
+class D<S, T> extends C<T> {}
+
+main() {
+  new D<String, bool>().test('bool', true);
+  new D<bool, int>().test('int', false);
+  new D().test('dynamic', true);
+}
diff --git a/tests/language/function_subtype_local5_test.dart b/tests/language/function_subtype_local5_test.dart
new file mode 100644
index 0000000..05cc7af
--- /dev/null
+++ b/tests/language/function_subtype_local5_test.dart
@@ -0,0 +1,42 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for local functions on generic type against generic
+// typedefs.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo<T>(T a, [String b]);
+typedef int Bar<T>(T a, [String b]);
+typedef int Baz<T>(T a, {String b});
+typedef int Boz<T>(T a);
+typedef int Biz<T>(T a, int b);
+
+class C<T> {
+  void test(String nameOfT, bool expectedResult) {
+    int foo(bool a, [String b]) => null;
+    int baz(bool a, {String b}) => null;
+
+    Expect.equals(expectedResult, foo is Foo<T>, 'foo is Foo<$nameOfT>');
+    Expect.equals(expectedResult, foo is Bar<T>, 'foo is Bar<$nameOfT>');
+    Expect.isFalse(foo is Baz<T>, 'foo is Baz<$nameOfT>');
+    Expect.equals(expectedResult, foo is Boz<T>, 'foo is Boz<$nameOfT>');
+    Expect.isFalse(foo is Biz<T>, 'foo is Biz<$nameOfT>');
+
+    Expect.isFalse(baz is Foo<T>, 'baz is Foo<$nameOfT>');
+    Expect.isFalse(baz is Bar<T>, 'baz is Bar<$nameOfT>');
+    Expect.equals(expectedResult, baz is Baz<T>, 'baz is Baz<$nameOfT>');
+    Expect.equals(expectedResult, baz is Boz<T>, 'baz is Boz<$nameOfT>');
+    Expect.isFalse(baz is Biz<T>, 'bar is Biz<$nameOfT>');
+  }
+}
+
+class D<S,T> extends C<T> {}
+
+main() {
+  new D<String, bool>().test('bool', true);
+  new D<bool, int>().test('int', false);
+  new D().test('dynamic', true);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_named1_test.dart b/tests/language/function_subtype_named1_test.dart
new file mode 100644
index 0000000..f697a45
--- /dev/null
+++ b/tests/language/function_subtype_named1_test.dart
@@ -0,0 +1,69 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping.
+
+import 'package:expect/expect.dart';
+
+void void_() {}
+void void__int(int i) {}
+void void___a_int({int a}) {}
+void void___a_int2({int a}) {}
+void void___b_int({int b}) {}
+void void___a_Object({Object a}) {}
+void void__int__a_int(int i1, {int a}) {}
+void void__int__a_int2(int i1, {int a}) {}
+void void___a_double({double a}) {}
+void void___a_int_b_int({int a, int b}) {}
+void void___a_int_b_int_c_int({int a, int b, int c}) {}
+void void___a_int_c_int({int a, int c}) {}
+void void___b_int_c_int({int b, int c}) {}
+void void___c_int({int c}) {}
+
+typedef void t_void_();
+typedef void t_void__int(int i);
+typedef void t_void___a_int({int a});
+typedef void t_void___a_int2({int a});
+typedef void t_void___b_int({int b});
+typedef void t_void___a_Object({Object a});
+typedef void t_void__int__a_int(int i1, {int a});
+typedef void t_void__int__a_int2(int i1, {int a});
+typedef void t_void___a_double({double a});
+typedef void t_void___a_int_b_int({int a, int b});
+typedef void t_void___a_int_b_int_c_int({int a, int b, int c});
+typedef void t_void___a_int_c_int({int a, int c});
+typedef void t_void___b_int_c_int({int b, int c});
+typedef void t_void___c_int({int c});
+
+main() {
+  // Test ({int a})->void <: ()->void.
+  Expect.isTrue(void___a_int is t_void_);
+  // Test ({int a})->void <: (int)->void.
+  Expect.isFalse(void___a_int is t_void__int);
+  // Test (int)->void <: ({int a})->void.
+  Expect.isFalse(void__int is t_void___a_int);
+  // Test ({int a})->void <: ({int a})->void.
+  Expect.isTrue(void___a_int is t_void___a_int2);
+  // Test ({int a})->void <: ({int b})->void.
+  Expect.isFalse(void___a_int is t_void___b_int);
+  // Test ({Object a})->void <: ({int a})->void.
+  Expect.isTrue(void___a_Object is t_void___a_int);
+  // Test ({int a})->void <: ({Object a})->void.
+  Expect.isTrue(void___a_int is t_void___a_Object);
+  // Test (int,{int a})->void <: (int,{int a})->void.
+  Expect.isTrue(void__int__a_int is t_void__int__a_int2);
+  // Test ({int a})->void <: ({double a})->void.
+  Expect.isFalse(void___a_int is t_void___a_double);
+  // Test ({int a})->void <: ({int a,int b})->void.
+  Expect.isFalse(void___a_int is t_void___a_int_b_int);
+  // Test ({int a,int b})->void <: ({int a})->void.
+  Expect.isTrue(void___a_int_b_int is t_void___a_int);
+  // Test ({int a,int b,int c})->void <: ({int a,int c})->void.
+  Expect.isTrue(void___a_int_b_int_c_int is t_void___a_int_c_int);
+  // Test ({int a,int b,int c})->void <: ({int b,int c})->void.
+  Expect.isTrue(void___a_int_b_int_c_int is t_void___b_int_c_int);
+  // Test ({int a,int b,int c})->void <: ({int c})->void.
+  Expect.isTrue(void___a_int_b_int_c_int is t_void___c_int);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_named2_test.dart b/tests/language/function_subtype_named2_test.dart
new file mode 100644
index 0000000..f2618bf
--- /dev/null
+++ b/tests/language/function_subtype_named2_test.dart
@@ -0,0 +1,56 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping.
+
+import 'package:expect/expect.dart';
+
+class C<T> {}
+
+typedef void void_();
+typedef void void__int(int i);
+typedef void void___a_int({int a});
+typedef void void___a_int2({int a});
+typedef void void___b_int({int b});
+typedef void void___a_Object({Object a});
+typedef void void__int__a_int(int i1, {int a});
+typedef void void__int__a_int2(int i1, {int a});
+typedef void void___a_double({double a});
+typedef void void___a_int_b_int({int a, int b});
+typedef void void___a_int_b_int_c_int({int a, int b, int c});
+typedef void void___a_int_c_int({int a, int c});
+typedef void void___b_int_c_int({int b, int c});
+typedef void void___c_int({int c});
+
+main() {
+  // Test ({int a})->void <: ()->void.
+  Expect.isTrue(new C<void___a_int>() is C<void_>);
+  // Test ({int a})->void <: (int)->void.
+  Expect.isFalse(new C<void___a_int>() is C<void__int>);
+  // Test (int)->void <: ({int a})->void.
+  Expect.isFalse(new C<void__int>() is C<void___a_int>);
+  // Test ({int a})->void <: ({int a})->void.
+  Expect.isTrue(new C<void___a_int>() is C<void___a_int2>);
+  // Test ({int a})->void <: ({int b})->void.
+  Expect.isFalse(new C<void___a_int>() is C<void___b_int>);
+  // Test ({Object a})->void <: ({int a})->void.
+  Expect.isTrue(new C<void___a_Object>() is C<void___a_int>);
+  // Test ({int a})->void <: ({Object a})->void.
+  Expect.isTrue(new C<void___a_int>() is C<void___a_Object>);
+  // Test (int,{int a})->void <: (int,{int a})->void.
+  Expect.isTrue(new C<void__int__a_int>() is C<void__int__a_int2>);
+  // Test ({int a})->void <: ({double a})->void.
+  Expect.isFalse(new C<void___a_int>() is C<void___a_double>);
+  // Test ({int a})->void <: ({int a,int b})->void.
+  Expect.isFalse(new C<void___a_int>() is C<void___a_int_b_int>);
+  // Test ({int a,int b})->void <: ({int a})->void.
+  Expect.isTrue(new C<void___a_int_b_int>() is C<void___a_int>);
+  // Test ({int a,int b,int c})->void <: ({int a,int c})->void.
+  Expect.isTrue(new C<void___a_int_b_int_c_int>() is C<void___a_int_c_int>);
+  // Test ({int a,int b,int c})->void <: ({int b,int c})->void.
+  Expect.isTrue(new C<void___a_int_b_int_c_int>() is C<void___b_int_c_int>);
+  // Test ({int a,int b,int c})->void <: ({int c})->void.
+  Expect.isTrue(new C<void___a_int_b_int_c_int>() is C<void___c_int>);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_not0_test.dart b/tests/language/function_subtype_not0_test.dart
new file mode 100644
index 0000000..7b8d864
--- /dev/null
+++ b/tests/language/function_subtype_not0_test.dart
@@ -0,0 +1,20 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check negative function subtyping tests.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo<T>(T t);
+typedef void Bar(int i);
+
+void bar(int i) {}
+
+void main() {
+  Expect.isFalse(bar is! Foo);
+  Expect.isTrue(bar is! Foo<bool>);
+  Expect.isFalse(bar is! Foo<int>);
+  Expect.isFalse(bar is! Bar);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_not1_test.dart b/tests/language/function_subtype_not1_test.dart
new file mode 100644
index 0000000..453197b5
--- /dev/null
+++ b/tests/language/function_subtype_not1_test.dart
@@ -0,0 +1,32 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check negative function subtyping tests.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo<T>(T t);
+typedef void Bar(int i);
+
+class Class<T> {
+  void bar(T i) {}
+}
+
+void main() {
+  Expect.isFalse(new Class().bar is! Foo);
+  Expect.isFalse(new Class().bar is! Foo<bool>);
+  Expect.isFalse(new Class().bar is! Foo<int>);
+  Expect.isFalse(new Class().bar is! Bar);
+
+  Expect.isFalse(new Class<int>().bar is! Foo);
+  Expect.isTrue(new Class<int>().bar is! Foo<bool>);
+  Expect.isFalse(new Class<int>().bar is! Foo<int>);
+  Expect.isFalse(new Class<int>().bar is! Bar);
+
+  Expect.isFalse(new Class<bool>().bar is! Foo);
+  Expect.isFalse(new Class<bool>().bar is! Foo<bool>);
+  Expect.isTrue(new Class<bool>().bar is! Foo<int>);
+  Expect.isTrue(new Class<bool>().bar is! Bar);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_not2_test.dart b/tests/language/function_subtype_not2_test.dart
new file mode 100644
index 0000000..c6daab5
--- /dev/null
+++ b/tests/language/function_subtype_not2_test.dart
@@ -0,0 +1,26 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check negative function subtyping tests.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo<T>(T t);
+typedef void Bar(int i);
+
+class Class<T> {
+  test(bool expectedResult, var o, String typeName) {
+    Expect.equals(expectedResult, o is! Foo<T>, "bar is! Foo<$typeName>");
+    Expect.isFalse(o is! Bar, "bar is! Bar");
+  }
+}
+
+void bar(int i) {}
+
+void main() {
+  new Class().test(false, bar, "dynamic");
+  new Class<int>().test(false, bar, "int");
+  new Class<bool>().test(true, bar, "bool");
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_not3_test.dart b/tests/language/function_subtype_not3_test.dart
new file mode 100644
index 0000000..27ff796
--- /dev/null
+++ b/tests/language/function_subtype_not3_test.dart
@@ -0,0 +1,29 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check negative function subtyping tests.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo<T>(T t);
+typedef void Bar(int i);
+
+class Class<T> {
+  test(bool expectedResult, var o, String typeName) {
+    void local() {
+      Expect.equals(expectedResult, o is! Foo<T>, "bar is! Foo<$typeName>");
+      Expect.isFalse(o is! Bar, "bar is! Bar");
+    }
+    local();
+  }
+}
+
+void bar(int i) {}
+
+void main() {
+  new Class().test(false, bar, "dynamic");
+  new Class<int>().test(false, bar, "int");
+  new Class<bool>().test(true, bar, "bool");
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_null.dart b/tests/language/function_subtype_null.dart
new file mode 100644
index 0000000..c235b81
--- /dev/null
+++ b/tests/language/function_subtype_null.dart
@@ -0,0 +1,17 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for null.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo(bool a, [String b]);
+typedef int Bar<T>(T a, [String b]);
+
+main() {
+  Expect.isFalse(null is Foo, 'null is Foo');
+  Expect.isFalse(null is Bar<bool>, 'null is Bar<bool>');
+  Expect.isFalse(null is Bar, 'null is Bar');
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_optional1_test.dart b/tests/language/function_subtype_optional1_test.dart
new file mode 100644
index 0000000..f66fe14
--- /dev/null
+++ b/tests/language/function_subtype_optional1_test.dart
@@ -0,0 +1,71 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping.
+
+import 'package:expect/expect.dart';
+
+void void_() {}
+void void__int(int i) {}
+void void___int([int i]) {}
+void void___int2([int i]) {}
+void void___Object([Object o]) {}
+void void__int__int(int i1, [int i2]) {}
+void void__int__int2(int i1, [int i2]) {}
+void void__int__int_int(int i1, [int i2, int i3]) {}
+void void___double(double d) {}
+void void___int_int([int i1, int i2]) {}
+void void___int_int_int([int i1, int i2, int i3]) {}
+void void___Object_int([Object o, int i]) {}
+
+typedef void t_void_();
+typedef void t_void__int(int i);
+typedef void t_void___int([int i]);
+typedef void t_void___int2([int i]);
+typedef void t_void___Object([Object o]);
+typedef void t_void__int__int(int i1, [int i2]);
+typedef void t_void__int__int2(int i1, [int i2]);
+typedef void t_void__int__int_int(int i1, [int i2, int i3]);
+typedef void t_void___double(double d);
+typedef void t_void___int_int([int i1, int i2]);
+typedef void t_void___int_int_int([int i1, int i2, int i3]);
+typedef void t_void___Object_int([Object o, int i]);
+
+main() {
+  // Test ([int])->void <: ()->void.
+  Expect.isTrue(void___int is t_void_);
+  // Test ([int])->void <: (int)->void.
+  Expect.isTrue(void___int is t_void__int);
+  // Test (int)->void <: ([int])->void.
+  Expect.isFalse(void__int is t_void___int);
+  // Test ([int])->void <: ([int])->void.
+  Expect.isTrue(void___int is t_void___int2);
+  // Test ([Object])->void <: ([int])->void.
+  Expect.isTrue(void___Object is t_void___int);
+  // Test ([int])->void <: ([Object])->void.
+  Expect.isTrue(void___int is t_void___Object);
+  // Test (int,[int])->void <: (int)->void.
+  Expect.isTrue(void__int__int is t_void__int);
+  // Test (int,[int])->void <: (int,[int])->void.
+  Expect.isTrue(void__int__int is t_void__int__int2);
+  // Test (int)->void <: ([int])->void.
+  Expect.isFalse(void__int is t_void___int);
+  // Test ([int,int])->void <: (int)->void.
+  Expect.isTrue(void___int_int is t_void__int);
+  // Test ([int,int])->void <: (int,[int])->void.
+  Expect.isTrue(void___int_int is t_void__int__int);
+  // Test ([int,int])->void <: (int,[int,int])->void.
+  Expect.isFalse(void___int_int is t_void__int__int_int);
+  // Test ([int,int,int])->void <: (int,[int,int])->void.
+  Expect.isTrue(void___int_int_int is t_void__int__int_int);
+  // Test ([int])->void <: ([double])->void.
+  Expect.isFalse(void___int is t_void___double);
+  // Test ([int])->void <: ([int,int])->void.
+  Expect.isFalse(void___int is t_void___int_int);
+  // Test ([int,int])->void <: ([int])->void.
+  Expect.isTrue(void___int_int is t_void___int);
+  // Test ([Object,int])->void <: ([int])->void.
+  Expect.isTrue(void___Object_int is t_void___int);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_optional2_test.dart b/tests/language/function_subtype_optional2_test.dart
new file mode 100644
index 0000000..4ca61e8
--- /dev/null
+++ b/tests/language/function_subtype_optional2_test.dart
@@ -0,0 +1,60 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping.
+
+import 'package:expect/expect.dart';
+
+class C<T> {}
+
+typedef void void_();
+typedef void void__int(int i);
+typedef void void___int([int i]);
+typedef void void___int2([int i]);
+typedef void void___Object([Object o]);
+typedef void void__int__int(int i1, [int i2]);
+typedef void void__int__int2(int i1, [int i2]);
+typedef void void__int__int_int(int i1, [int i2, int i3]);
+typedef void void___double(double d);
+typedef void void___int_int([int i1, int i2]);
+typedef void void___int_int_int([int i1, int i2, int i3]);
+typedef void void___Object_int([Object o, int i]);
+
+main() {
+  // Test ([int])->void <: ()->void.
+  Expect.isTrue(new C<void___int>() is C<void_>);
+  // Test ([int])->void <: (int)->void.
+  Expect.isTrue(new C<void___int>() is C<void__int>);
+  // Test (int)->void <: ([int])->void.
+  Expect.isFalse(new C<void__int>() is C<void___int>);
+  // Test ([int])->void <: ([int])->void.
+  Expect.isTrue(new C<void___int>() is C<void___int2>);
+  // Test ([Object])->void <: ([int])->void.
+  Expect.isTrue(new C<void___Object>() is C<void___int>);
+  // Test ([int])->void <: ([Object])->void.
+  Expect.isTrue(new C<void___int>() is C<void___Object>);
+  // Test (int,[int])->void <: (int)->void.
+  Expect.isTrue(new C<void__int__int>() is C<void__int>);
+  // Test (int,[int])->void <: (int,[int])->void.
+  Expect.isTrue(new C<void__int__int>() is C<void__int__int2>);
+  // Test (int)->void <: ([int])->void.
+  Expect.isFalse(new C<void__int>() is C<void___int>);
+  // Test ([int,int])->void <: (int)->void.
+  Expect.isTrue(new C<void___int_int>() is C<void__int>);
+  // Test ([int,int])->void <: (int,[int])->void.
+  Expect.isTrue(new C<void___int_int>() is C<void__int__int>);
+  // Test ([int,int])->void <: (int,[int,int])->void.
+  Expect.isFalse(new C<void___int_int>() is C<void__int__int_int>);
+  // Test ([int,int,int])->void <: (int,[int,int])->void.
+  Expect.isTrue(new C<void___int_int_int>() is C<void__int__int_int>);
+  // Test ([int])->void <: ([double])->void.
+  Expect.isFalse(new C<void___int>() is C<void___double>);
+  // Test ([int])->void <: ([int,int])->void.
+  Expect.isFalse(new C<void___int>() is C<void___int_int>);
+  // Test ([int,int])->void <: ([int])->void.
+  Expect.isTrue(new C<void___int_int>() is C<void___int>);
+  // Test ([Object,int])->void <: ([int])->void.
+  Expect.isTrue(new C<void___Object_int>() is C<void___int>);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_setter0_test.dart b/tests/language/function_subtype_setter0_test.dart
new file mode 100644
index 0000000..7f48f1b
--- /dev/null
+++ b/tests/language/function_subtype_setter0_test.dart
@@ -0,0 +1,40 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for implicit setters.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo();
+class A<T> {}
+
+class C {
+  Foo foo;
+  A<int> bar;
+}
+
+class D {
+  Foo foo;
+  A<int> bar;
+}
+
+test(var c) {
+  bool inCheckedMode = false;
+  try {
+    var x = 42;
+    String a = x;
+  } catch (e) {
+    inCheckedMode = true;
+  }
+  if (inCheckedMode) {
+    Expect.throws(() => c.foo = 1, (e) => true);
+  }
+  c.foo = () {};
+}
+
+void main() {
+  test(new C());
+  test(new D());
+}
diff --git a/tests/language/function_subtype_top_level0_test.dart b/tests/language/function_subtype_top_level0_test.dart
new file mode 100644
index 0000000..7e68c05
--- /dev/null
+++ b/tests/language/function_subtype_top_level0_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for top level functions.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo(bool a, [String b]);
+typedef int Bar(bool a, [String b]);
+typedef int Baz(bool a, {String b});
+typedef int Boz(bool a);
+
+int foo(bool a, [String b]) => null;
+int baz(bool a, {String b}) => null;
+int boz(bool a, {int b}) => null;
+
+main() {
+  Expect.isTrue(foo is Foo, 'foo is Foo');
+  Expect.isTrue(foo is Bar, 'foo is Bar');
+  Expect.isFalse(foo is Baz, 'foo is Baz');
+  Expect.isTrue(foo is Boz, 'foo is Boz');
+
+  Expect.isFalse(baz is Foo, 'foo is Foo');
+  Expect.isFalse(baz is Bar, 'foo is Bar');
+  Expect.isTrue(baz is Baz, 'foo is Baz');
+  Expect.isTrue(baz is Boz, 'foo is Boz');
+
+  Expect.isFalse(boz is Foo, 'foo is Foo');
+  Expect.isFalse(boz is Bar, 'foo is Bar');
+  Expect.isFalse(boz is Baz, 'foo is Baz');
+  Expect.isTrue(boz is Boz, 'foo is Boz');
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_top_level1_test.dart b/tests/language/function_subtype_top_level1_test.dart
new file mode 100644
index 0000000..b82bea1
--- /dev/null
+++ b/tests/language/function_subtype_top_level1_test.dart
@@ -0,0 +1,42 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for top level functions.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo<T>(T a, [String b]);
+typedef int Bar<T>(T a, [String b]);
+typedef int Baz<T>(T a, {String b});
+typedef int Boz<T>(T a);
+
+int foo(bool a, [String b]) => null;
+int baz(bool a, {String b}) => null;
+int boz(bool a, {int b}) => null;
+
+class C<T> {
+  void test(String nameOfT, bool expectedResult) {
+    Expect.equals(expectedResult, foo is Foo<T>, 'foo is Foo<$nameOfT>');
+    Expect.equals(expectedResult, foo is Bar<T>, 'foo is Bar<$nameOfT>');
+    Expect.isFalse(foo is Baz<T>, 'foo is Baz<$nameOfT>');
+    Expect.equals(expectedResult, foo is Boz<T>, 'foo is Boz<$nameOfT>');
+
+    Expect.isFalse(baz is Foo<T>, 'foo is Foo<$nameOfT>');
+    Expect.isFalse(baz is Bar<T>, 'foo is Bar<$nameOfT>');
+    Expect.equals(expectedResult, baz is Baz<T>, 'foo is Baz<$nameOfT>');
+    Expect.equals(expectedResult, baz is Boz<T>, 'foo is Boz<$nameOfT>');
+
+    Expect.isFalse(boz is Foo<T>, 'foo is Foo<$nameOfT>');
+    Expect.isFalse(boz is Bar<T>, 'foo is Bar<$nameOfT>');
+    Expect.isFalse(boz is Baz<T>, 'foo is Baz<$nameOfT>');
+    Expect.equals(expectedResult, boz is Boz<T>, 'foo is Boz<$nameOfT>');
+  }
+}
+
+main() {
+  new C<bool>().test('bool', true);
+  new C<int>().test('int', false);
+  new C().test('dynamic', true);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_typearg0_test.dart b/tests/language/function_subtype_typearg0_test.dart
new file mode 100644
index 0000000..58f9d98
--- /dev/null
+++ b/tests/language/function_subtype_typearg0_test.dart
@@ -0,0 +1,29 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping with type variables in factory constructors.
+
+import 'package:expect/expect.dart';
+
+typedef void Foo();
+
+class A<T> {
+  bool foo(a) => a is T;
+}
+
+void bar1() {}
+void bar2(i) {}
+
+void main() {
+  void bar3() {}
+  void bar4(i) {}
+
+  Expect.isTrue(new A<Foo>().foo(bar1));
+  Expect.isFalse(new A<Foo>().foo(bar2));
+  Expect.isTrue(new A<Foo>().foo(bar3));
+  Expect.isFalse(new A<Foo>().foo(bar4));
+  Expect.isTrue(new A<Foo>().foo((){}));
+  Expect.isFalse(new A<Foo>().foo((i){}));
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_typearg1_test.dart b/tests/language/function_subtype_typearg1_test.dart
new file mode 100644
index 0000000..5575b91
--- /dev/null
+++ b/tests/language/function_subtype_typearg1_test.dart
@@ -0,0 +1,20 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping of type arguments.
+
+import 'package:expect/expect.dart';
+
+class C<T> {}
+
+class I {}
+class J extends I {}
+
+typedef void f1(C<J> c);
+typedef void f2(C<I> c);
+
+main() {
+  Expect.isTrue(new C<f2>() is C<f1>);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_typearg2_test.dart b/tests/language/function_subtype_typearg2_test.dart
new file mode 100644
index 0000000..0859133
--- /dev/null
+++ b/tests/language/function_subtype_typearg2_test.dart
@@ -0,0 +1,20 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping of type arguments.
+
+import 'package:expect/expect.dart';
+
+class C<T> {}
+
+class I {}
+class J extends I {}
+
+typedef void f1(C<J> c);
+typedef void f2(C<I> c);
+
+main() {
+  Expect.isTrue(new C<f1>() is C<f2>);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_typearg3_test.dart b/tests/language/function_subtype_typearg3_test.dart
new file mode 100644
index 0000000..723e090
--- /dev/null
+++ b/tests/language/function_subtype_typearg3_test.dart
@@ -0,0 +1,20 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping of type arguments.
+
+import 'package:expect/expect.dart';
+
+class C<T> {}
+
+class I {}
+class J extends I {}
+
+typedef J f1();
+typedef I f2();
+
+main() {
+  Expect.isTrue(new C<f1>() is C<f2>);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_typearg4_test.dart b/tests/language/function_subtype_typearg4_test.dart
new file mode 100644
index 0000000..6d95de5
--- /dev/null
+++ b/tests/language/function_subtype_typearg4_test.dart
@@ -0,0 +1,20 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping of type arguments.
+
+import 'package:expect/expect.dart';
+
+class C<T> {}
+
+class I {}
+class J extends I {}
+
+typedef I f1();
+typedef J f2();
+
+main() {
+  Expect.isTrue(new C<f1>() is C<f2>);
+}
\ No newline at end of file
diff --git a/tests/language/int2_test.dart b/tests/language/int2_test.dart
new file mode 100644
index 0000000..633bd10
--- /dev/null
+++ b/tests/language/int2_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// Regression test for dart2js that used to throw NoSuchMethod if an
+// int did not fit in the SMI range.
+
+import "package:expect/expect.dart";
+
+main() {
+  // dart2js knows that this list is int or null.
+  var b = [null, 10000000000000000000000000000000000000];
+
+  // Use b[1] twice to ensure dart2js realizes it's the same value
+  // after type propagation.
+
+  // dart2js will inline an ArgumentError check on b[a].
+  42 + b[1];
+  // dart2js will inline a NoSuchMethodError check.
+  var c = b[1] & 1;
+  Expect.equals(0, c);
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index e55fc34..ad8bd91 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -459,7 +459,6 @@
 closure_in_initializer_test: Fail
 super_first_constructor_test: Fail
 # VM specific tests.
-disable_privacy_test: Pass, Fail, Ok
 # This test hard codes name of file being run and precise position.
 generic_test: Fail, Ok
 # Minified mode failures.
@@ -515,6 +514,49 @@
 bound_closure_equality_test: Fail # Issue 10849
 
 [ $compiler == dart2dart && $minified ]
+dynamic_test: Fail # dartbug.com/11468
+function_subtype_bound_closure0_test: Fail # dartbug.com/11468
+function_subtype_bound_closure1_test: Fail # dartbug.com/11468
+function_subtype_bound_closure2_test: Fail # dartbug.com/11468
+function_subtype_bound_closure5_test: Fail # dartbug.com/11468
+function_subtype_bound_closure6_test: Fail # dartbug.com/11468
+function_subtype_bound_closure7_test: Fail # dartbug.com/11468
+function_subtype_cast0_test: Fail # dartbug.com/11468
+function_subtype_cast1_test: Fail # dartbug.com/11468
+function_subtype_cast2_test: Fail # dartbug.com/11468
+function_subtype_cast3_test: Fail # dartbug.com/11468
+function_subtype_factory0_test: Fail # dartbug.com/11468
+function_subtype_local1_test: Fail # dartbug.com/11468
+function_subtype_local5_test: Fail # dartbug.com/11468
+function_subtype_not0_test: Fail # dartbug.com/11468
+function_subtype_not1_test: Fail # dartbug.com/11468
+function_subtype_not2_test: Fail # dartbug.com/11468
+function_subtype_not3_test: Fail # dartbug.com/11468
+function_subtype_top_level1_test: Fail # dartbug.com/11468
+function_type_alias2_test: Fail # dartbug.com/11468
+function_type_alias3_test: Fail # dartbug.com/11468
+function_type_alias4_test: Fail # dartbug.com/11468
+function_type_alias6_test: Fail # dartbug.com/11468
+function_type_alias_test: Fail # dartbug.com/11468
+method_override_test: Fail # dartbug.com/11468
+
+function_subtype0_test: Fail # dartbug.com/11467
+function_subtype1_test: Fail # dartbug.com/11467
+function_subtype_bound_closure3_test: Fail # dartbug.com/11467
+function_subtype_bound_closure4_test: Fail # dartbug.com/11467
+function_subtype_call0_test: Fail # dartbug.com/11467
+function_subtype_call1_test: Fail # dartbug.com/11467
+function_subtype_call2_test: Fail # dartbug.com/11467
+function_subtype_inline0_test: Fail # dartbug.com/11467
+function_subtype_local0_test: Fail # dartbug.com/11467
+function_subtype_local2_test: Fail # dartbug.com/11467
+function_subtype_local3_test: Fail # dartbug.com/11467
+function_subtype_local4_test: Fail # dartbug.com/11467
+function_subtype_named1_test: Fail # dartbug.com/11467
+function_subtype_named2_test: Fail # dartbug.com/11467
+function_subtype_optional1_test: Fail # dartbug.com/11467
+function_subtype_optional2_test: Fail # dartbug.com/11467
+function_subtype_top_level0_test: Fail # dartbug.com/11467
 
 super_getter_setter_test: Fail # Issue 11065.
 
@@ -526,44 +568,27 @@
 invocation_mirror_test: Fail, OK # hardcoded names.
 super_call4_test: Fail, OK # hardcoded names.
 
+
 [ $arch == simarm || $arch == arm ]
-bit_operations_test: Crash, Fail
 deopt_smi_op_test: Fail
 gc_test: Crash
 invocation_mirror_test: Fail
-load_to_load_forwarding_vm_test: Fail
-named_parameters_with_conversions_test: Pass, Crash
-arithmetic_test: Pass, Crash, Fail # Fails on Mac
-left_shift_test: Pass, Fail # Fails on Mac
-positive_bit_operations_test: Pass, Fail, Crash # Fails and crashes on Mac
+named_parameters_with_conversions_test: Pass, Crash # Passes on Mac.
+stack_overflow_test: Crash, Pass # Passes on HW in release mode.
+stack_overflow_stacktrace_test: Crash, Pass # Passes on HW in release mode.
 
 
-# large_implicit_getter_test Passes on ReleaseARM, Crashes in SIMARM and
-# DebugARM. Should crash on ReleaseARM, but there is no exception on an
-# unaligned access. stack_overflow_test and  _stacktrace_test have the same
-# problem.
-large_implicit_getter_test: Crash, Pass
-stack_overflow_test: Crash, Pass
-stack_overflow_stacktrace_test: Crash, Pass
-
-[ ($arch == simarm || $arch == arm) && $mode == debug ]
-char_escape_test: Pass, Crash
-
 [ $arch == mips ]
 *: Skip
 
+
 [ $arch == simmips ]
-arithmetic_test: Fail, Crash
-bit_operations_test: Crash, Fail
-char_escape_test: Pass, Crash
+arithmetic_test: Crash  # Too far relative branch.
 deopt_smi_op_test: Fail
-div_with_power_of_two_test: Fail
 gc_test: Crash
 invocation_mirror_test: Fail
+large_implicit_getter_test: Crash
 load_to_load_forwarding_vm_test: Fail
 named_parameters_with_conversions_test: Pass, Crash
-positive_bit_operations_test: Pass, Fail, Crash
-left_shift_test: Pass, Fail
-large_implicit_getter_test: Crash, Pass
-stack_overflow_test: Crash, Pass
-stack_overflow_stacktrace_test: Crash, Pass
+stack_overflow_test: Crash
+stack_overflow_stacktrace_test: Crash
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index 27a984d..2d51605 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -10,9 +10,6 @@
 bad_named_parameters_test: fail
 bad_override_test/01: fail
 bad_override_test/02: fail
-bad_override_test/03: fail
-bad_override_test/04: fail
-bad_override_test/05: fail
 black_listed_test/11: fail
 body_less_constructor_wrong_arg_negative_test: fail
 built_in_identifier_prefix_test: fail
@@ -42,7 +39,6 @@
 compile_time_constant_checked3_test/04: fail
 compile_time_constant_checked3_test/06: fail
 compile_time_constant_e_test: fail
-const_syntax_test/06: fail
 constructor2_negative_test: fail
 constructor3_negative_test: fail
 constructor_call_wrong_argument_count_negative_test: fail
@@ -64,8 +60,6 @@
 factory5_test/00: fail
 factory_implementation_test/none: fail
 factory_redirection2_test/01: fail
-fauxverride_test/03: fail
-fauxverride_test/05: fail
 field_method4_negative_test: fail
 field_override_test/01: fail
 final_for_in_variable_test/01: fail
@@ -89,10 +83,7 @@
 implicit_this_test/01: fail
 implicit_this_test/04: fail
 import_combinators_negative_test: fail
-inst_field_initializer1_negative_test: fail
 instance_call_wrong_argument_count_negative_test: fail
-instance_method2_negative_test: fail
-instance_method_negative_test: fail
 instantiate_type_variable_negative_test: fail
 interface_static_non_final_fields_negative_test: fail
 interface_test/00: fail
@@ -127,15 +118,9 @@
 no_such_method_negative_test: fail
 non_const_super_negative_test: fail
 number_identifier_negative_test: fail
-override_field_method1_negative_test: fail
-override_field_method2_negative_test: fail
-override_field_method4_negative_test: fail
-override_field_method5_negative_test: fail
 override_field_test/01: fail
 override_field_test/02: fail
 override_field_test/03: fail
-override_method_with_field_test/01: fail
-override_method_with_field_test/02: fail
 prefix10_negative_test: fail
 prefix11_negative_test: fail
 prefix12_negative_test: fail
@@ -154,7 +139,6 @@
 pseudo_kw_illegal_test/14: fail
 pseudo_kw_test: fail
 redirecting_factory_infinite_steps_test/01: fail
-redirecting_factory_infinite_steps_test/02: fail
 scope_negative_test: fail
 setter3_test/01: fail
 setter3_test/02: fail
@@ -186,13 +170,8 @@
 type_variable_bounds2_test/04: fail
 type_variable_bounds2_test/06: fail
 type_variable_bounds_test/00: fail
-type_variable_bounds_test/01: fail
-type_variable_bounds_test/02: fail
 type_variable_bounds_test/03: fail
 type_variable_bounds_test/04: fail
-type_variable_bounds_test/06: fail
-type_variable_bounds_test/07: fail
-type_variable_bounds_test/09: fail
 type_variable_identifier_expression_negative_test: fail
 type_variable_static_context_negative_test: fail
 unresolved_in_factory_negative_test: fail
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index be8fb29..4043be7 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -135,7 +135,6 @@
 override_field_test/02: fail
 override_field_test/03: fail
 override_method_with_field_test/01: fail
-override_method_with_field_test/02: fail
 prefix10_negative_test: fail
 prefix11_negative_test: fail
 prefix12_negative_test: fail
@@ -173,7 +172,6 @@
 syntax_test/31: fail
 syntax_test/32: fail
 syntax_test/33: fail
-ternary_test: fail
 throw7_negative_test: fail
 type_error_test: fail
 type_parameter_test/01: fail
@@ -196,8 +194,6 @@
 type_variable_bounds_test/09: fail
 type_variable_identifier_expression_negative_test: fail
 type_variable_static_context_negative_test: fail
-unary2_test: fail
-unary_test: fail
 unresolved_in_factory_negative_test: fail
 unresolved_top_level_method_negative_test: fail
 unresolved_top_level_var_negative_test: fail
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index cab3e41..a21901b 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -39,9 +39,6 @@
 *vm_negative_test: Skip
 
 [ $compiler == dart2js && $checked ]
-function_type_alias6_test: Crash # dartbug.com/9792
-
-prefix16_test: Fail # dartbug.com/7354
 default_factory2_test/01: Fail
 type_variable_bounds_test/01: Fail
 type_variable_bounds_test/02: Fail
@@ -56,13 +53,13 @@
 f_bounded_quantification_test/02: Fail
 closure_type_test: Fail # does not detect type error in checked mode.
 type_annotation_test/09: Fail # Named constructors interpreted as a type.
-prefix15_test: Fail # Issue 5022
-local_function2_test: Fail # Issue 5022
+function_subtype_setter0_test: Fail # dartbug.com/11273
 
 [ $compiler == dart2js && $unchecked ]
 factory_redirection_test/14: Fail # redirecting to redirecting factory
 type_checks_in_factory_method_test: Fail # Expect.equals(expected: <true>, actual: <false>) fails. -- checked mode test.
 
+prefix16_test: Fail # dartbug.com/9056
 assertion_test: Fail
 type_variable_bounds_test/07: Fail # Wrongly reports compile-time error.
 
@@ -87,6 +84,7 @@
 compile_time_constant_checked3_test/06: Fail, OK
 
 [ $compiler == dart2js ]
+function_type_alias6_test: Crash # dartbug.com/9792
 branch_canonicalization_test: Fail # Issue 638.
 div_with_power_of_two_test: Fail # Issue 8301.
 class_literal_test: Fail # Issue 7626.
@@ -122,30 +120,19 @@
 infinity_test: Fail # Issue 4984
 positive_bit_operations_test: Fail # (floitsch): This will be fixed when dart2js uses unsigned input for >>.
 
-compile_time_constant8_test: Fail # We don't take the generic type into account yet.
-canonical_const_test: Fail # We don't take the generic type into account yet.
 
 # Support for optional parameters not conform to latest spec.
-function_type_alias_test: Fail # http://dartbug.com/9058
-function_type_alias2_test: Fail
 named_parameters_type_test: Fail
 positional_parameters_type_test: Fail
 
 # Compilation errors.
 const_var_test: Fail # Map literals take 2 type arguments.
 map_literal3_test: Fail # Map literals take 2 type arguments.
-ct_const_test: Fail # We don't take the generic type into account yet.
-dynamic_test: Fail # cannot resolve type F1
 constructor_redirect2_test/03: Fail # redirecting ctor with initializing formal
-factory3_test: Fail # internal error: visitIs for type variables not implemented
-function_type_alias2_test: Fail # cannot resolve type f1
-function_type_alias3_test: Fail # cannot resolve type F
-function_type_alias4_test: Fail # cannot resolve type F
 function_type_alias5_test/00: Fail # visitIs for typedefs not implemented
 function_type_alias5_test/01: Fail # visitIs for typedefs not implemented
 function_type_alias5_test/02: Fail # visitIs for typedefs not implemented
 function_type_alias7_test/00: Fail # wrongly accepts default values in typedef
-function_type_alias_test: Fail # cannot resolve type Fun
 generic_test: Fail # cannot resolve type T
 get_set_syntax_test/00: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
 get_set_syntax_test/01: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
@@ -241,9 +228,7 @@
 interface_factory3_negative_test: Fail # Negative language test.
 interface_factory_constructor_negative_test: Fail # Negative language test.
 list_literal1_negative_test: Fail # Negative language test.
-list_literal2_negative_test: Fail # Negative language test.
 map_literal1_negative_test: Fail # Negative language test.
-map_literal2_negative_test: Fail # Negative language test.
 number_identifier_negative_test: Fail # Negative language test.
 operator1_negative_test: Fail # Negative language test.
 prefix23_negative_test: Fail # Negative language test.
@@ -262,7 +247,6 @@
 string_interpolation7_negative_test: Fail # Negative language test.
 throw7_negative_test: Fail # Negative language test.
 
-disable_privacy_test: Fail, OK # VM specific test.
 numbers_test: Fail, OK # (unintended?) VM specific test.
 
 final_syntax_test/01: Fail # Missing error for uninitialized final field.
@@ -303,9 +287,9 @@
 double_to_string_as_fixed_test: Fail
 double_to_string_as_precision3_test: Fail
 expect_test: Fail
-factory3_test: Fail
 stack_overflow_test: Fail
 stack_overflow_stacktrace_test: Fail
+inlined_throw_test: Fail # BUG(11480): Triage.
 
 
 [ $compiler == dart2js && $runtime == safari ]
@@ -327,3 +311,6 @@
 string_interpolate_npe_test: Fail
 closure_call_wrong_argument_count_negative_test: Skip
 label_test: Skip
+
+[ $compiler == dart2js && $minified ]
+function_subtype_inline0_test: Fail # Issue 11469
diff --git a/tests/language/load_to_load_forwarding_vm_test.dart b/tests/language/load_to_load_forwarding_vm_test.dart
index b77854f..2f0a766 100644
--- a/tests/language/load_to_load_forwarding_vm_test.dart
+++ b/tests/language/load_to_load_forwarding_vm_test.dart
@@ -51,7 +51,6 @@
   return arr.length;
 }
 
-
 testPhiRepresentation(f, arr) {
   if (f) {
     arr[0] = arr[0] + arr[1];
@@ -61,7 +60,6 @@
   return arr[0];
 }
 
-
 testPhiConvertions(f, arr) {
   if (f) {
     arr[0] = arr[1];
@@ -71,6 +69,130 @@
   return arr[0];
 }
 
+class M {
+  var x;
+  M(this.x);
+}
+
+fakeAliasing(arr) {
+  var a = new M(10);
+  var b = new M(10);
+  var c = arr.length;
+
+  if (c * c != c * c) {
+    arr[0] = a;  // Escape.
+    arr[0] = b;
+  }
+
+  return c * c;  // Deopt point.
+}
+
+class X {
+  var next;
+  X(this.next);
+}
+
+testPhiForwarding(obj) {
+  if (obj.next == null) {
+    return 1;
+  }
+
+  var len = 0;
+  while (obj != null) {
+    len++;
+    obj = obj.next;  // This load should not be forwarded.
+  }
+
+  return len;
+}
+
+testPhiForwarding2(obj) {
+  if (obj.next == null) {
+    return 1;
+  }
+
+  var len = 0, next = null;
+  while ((obj != null) && len < 2) {
+    len++;
+    obj = obj.next;  // This load should be forwarded.
+    next = obj.next;
+  }
+
+  return len;
+}
+
+class V {
+  final f;
+  V(this.f);
+}
+
+testPhiForwarding3() {
+  var a = new V(-0.1);
+  var c = new V(0.0);
+  var b = new V(0.1);
+
+  for (var i = 0; i < 3; i++) {
+    var af = a.f;
+    var bf = b.f;
+    var cf = c.f;
+    a = new V(cf);
+    b = new V(af);
+    c = new V(bf);
+  }
+
+  Expect.equals(-0.1, a.f);
+  Expect.equals(0.1, b.f);
+  Expect.equals(0.0, c.f);
+}
+
+testPhiForwarding4() {
+  var a = new V(-0.1);
+  var b = new V(0.1);
+  var c = new V(0.0);
+
+  var result = new List(9);
+  for (var i = 0, j = 0; i < 3; i++) {
+    result[j++] = a.f;
+    result[j++] = b.f;
+    result[j++] = c.f;
+    var xa = a;
+    var xb = b;
+    a = c;
+    b = xa;
+    c = xb;
+  }
+
+  Expect.listEquals([-0.1, 0.1, 0.0,
+                     0.0, -0.1, 0.1,
+                     0.1, 0.0, -0.1], result);
+}
+
+class U {
+  var x, y;
+  U() : x = 0, y = 0;
+}
+
+testEqualPhisElimination() {
+  var u = new U();
+  var v = new U();
+  var sum = 0;
+  for (var i = 0; i < 3; i++) {
+    u.x = i;
+    u.y = i;
+    if ((i & 1) == 1) {
+      v.x = i + 1;
+      v.y = i + 1;
+    } else {
+      v.x = i - 1;
+      v.y = i - 1;
+    }
+    sum += v.x + v.y;
+  }
+  Expect.equals(4, sum);
+  Expect.equals(2, u.x);
+  Expect.equals(2, u.y);
+}
+
 main() {
   final fixed = new List(10);
   final growable = [];
@@ -82,12 +204,19 @@
   testPhiRepresentation(true, f64List);
   testPhiRepresentation(false, f64List);
 
+  final obj = new X(new X(new X(null)));
+
   for (var i = 0; i < 2000; i++) {
     Expect.listEquals([0x02010000, 0x03020100], foo(new A(0, 0)));
     Expect.listEquals([0x02010000, 0x03020100], bar(new A(0, 0), false));
     Expect.listEquals([0x04020000, 0x03020100], bar(new A(0, 0), true));
     testImmutableVMFields(fixed, true);
     testPhiRepresentation(true, f64List);
+    testPhiForwarding(obj);
+    testPhiForwarding2(obj);
+    testPhiForwarding3();
+    testPhiForwarding4();
+    testEqualPhisElimination();
   }
 
   Expect.equals(1, testImmutableVMFields([], false));
@@ -99,9 +228,14 @@
   u32List[0] = 0;
   u32List[1] = 0x3FFFFFFF;
   u32List[2] = 0x7FFFFFFF;
-  
+
   for (var i = 0; i < 4000; i++) {
     testPhiConvertions(true, u32List);
     testPhiConvertions(false, u32List);
   }
+
+  final escape = new List(1);
+  for (var i = 0; i < 10000; i++) {
+    fakeAliasing(escape);
+  }
 }
diff --git a/tests/language/mixin_regress_11398_test.dart b/tests/language/mixin_regress_11398_test.dart
new file mode 100644
index 0000000..0336db4
--- /dev/null
+++ b/tests/language/mixin_regress_11398_test.dart
@@ -0,0 +1,43 @@
+// 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:expect/expect.dart";
+
+void main() {
+  var hva = new HasValueA();
+  hva.value = '42';
+  Expect.equals('42', hva.value);
+
+  var hvb = new HasValueB();
+  hvb.value = '87';
+  Expect.equals('87', hvb.value);
+
+  var hvc = new HasValueC();
+  hvc.value = '99';
+  Expect.equals('99', hvc.value);
+}
+
+abstract class Delegate {
+  String invoke(String value);
+}
+
+abstract class DelegateMixin {
+  String invoke(String value) => value;
+}
+
+abstract class HasValueMixin implements Delegate {
+  String _value;
+  set value(String value) { _value = invoke(value); }
+  String get value => _value;
+}
+
+class HasValueA extends Object with HasValueMixin, DelegateMixin {
+}
+
+class HasValueB extends Object with DelegateMixin, HasValueMixin {
+}
+
+class HasValueC extends Object with HasValueMixin {
+  String invoke(String value) => value;
+}
diff --git a/tests/language/no_such_method_dispatcher_test.dart b/tests/language/no_such_method_dispatcher_test.dart
new file mode 100644
index 0000000..8686480
--- /dev/null
+++ b/tests/language/no_such_method_dispatcher_test.dart
@@ -0,0 +1,32 @@
+// 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.
+// VMOptions=--optimization-counter-threshold=100
+
+import "package:expect/expect.dart";
+
+// Test that noSuchMethod dispatching and auto-closurization work correctly.
+
+class A {
+  noSuchMethod(m) {
+    return 123;
+  }
+  bar(x) => x + 1;
+}
+
+class B extends A { }
+
+main() {
+  var a = new A();
+  for (var i = 0; i < 100; ++i) Expect.equals(123, a.foo());
+  Expect.throws(() => (a.foo)());
+  Expect.equals("123", (a.foo).toString());
+
+  var b = new B();
+  for (var i = 0; i < 100; ++i) {
+    Expect.equals(2, b.bar(1));
+    Expect.equals(123, b.bar());
+    Expect.equals(2, b.bar(1));
+  }
+}
+
diff --git a/tests/language/type_variable_closure_test.dart b/tests/language/type_variable_closure_test.dart
new file mode 100644
index 0000000..7fd7381
--- /dev/null
+++ b/tests/language/type_variable_closure_test.dart
@@ -0,0 +1,27 @@
+// 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:expect/expect.dart";
+
+class C<T> {
+  C.foo() {
+    x = (a) => a is T;
+  }
+  C.bar() {
+    x = (a) => a is! T;
+  }
+  C.baz() {
+    x = (a) => a as T;
+  }
+  var x;
+}
+
+main() {
+  Expect.isTrue(new C<int>.foo().x(1));
+  Expect.isFalse(new C<int>.foo().x('1'));
+  Expect.isFalse(new C<int>.bar().x(1));
+  Expect.isTrue(new C<int>.bar().x('1'));
+  Expect.equals(new C<int>.baz().x(1), 1);
+  Expect.throws(() => new C<int>.baz().x('1'));
+}
diff --git a/tests/lib/async/stream_first_where_test.dart b/tests/lib/async/stream_first_where_test.dart
new file mode 100644
index 0000000..41d7325
--- /dev/null
+++ b/tests/lib/async/stream_first_where_test.dart
@@ -0,0 +1,28 @@
+// 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 stream_controller_async_test;
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'dart:isolate';
+import '../../../pkg/unittest/lib/unittest.dart';
+import 'event_helper.dart';
+import 'stream_state_helper.dart';
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  Events sentEvents = new Events()..close();
+
+  // Make sure that firstWhere allows to return instances of types that are
+  // different than the generic type of the stream.
+  test("firstWhere with super class", () {
+    StreamController c = new StreamController<B>();
+    Future f = c.stream.firstWhere((x) => false, defaultValue: () => const A());
+    f.then(expectAsync1((v) { Expect.equals(const A(), v); }));
+    sentEvents.replay(c);
+  });
+}
diff --git a/tests/lib/async/stream_last_where_test.dart b/tests/lib/async/stream_last_where_test.dart
new file mode 100644
index 0000000..c02d608
--- /dev/null
+++ b/tests/lib/async/stream_last_where_test.dart
@@ -0,0 +1,28 @@
+// 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 stream_controller_async_test;
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'dart:isolate';
+import '../../../pkg/unittest/lib/unittest.dart';
+import 'event_helper.dart';
+import 'stream_state_helper.dart';
+
+class A { const A(); }
+class B extends A { const B(); }
+
+main() {
+  Events sentEvents = new Events()..close();
+
+  // Make sure that lastWhere allows to return instances of types that are
+  // different than the generic type of the stream.
+  test("lastWhere with super class", () {
+    StreamController c = new StreamController<B>();
+    Future f = c.stream.lastWhere((x) => false, defaultValue: () => const A());
+    f.then(expectAsync1((v) { Expect.equals(const A(), v); }));
+    sentEvents.replay(c);
+  });
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index e26f707..2488346 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -16,18 +16,19 @@
 typed_data/float32x4_unbox_phi_test: Fail, OK
 typed_data/float32x4_unbox_regress_test: Fail, OK
 
+[ $compiler == dart2js && $checked ]
+async/catch_errors20_test: Fail # Issue 11470
+
 [ $compiler == dart2js && ($runtime == d8 || $runtime == ie9) ]
 typed_data/byte_data_test: Fail, OK # d8/ie9 doesn't support DataView
 
 [ $compiler == dart2js && $minified ]
-mirrors/disable_tree_shaking_test: Fail # Issue 6490
-mirrors/metadata_test: Fail
-mirrors/mirrors_resolve_fields_test: Fail # Issue 6490
 mirrors/reflect_model_test: Fail # Issue 6490
-mirrors/reflectively_instantiate_uninstantiated_class_test: Fail # Issue 6490
 mirrors/to_string_test: Fail # Issue 6490
 
 [ $csp ]
+mirrors/intercepted_class_test: Fail # Issue 6490
+mirrors/intercepted_object_test: Fail # Issue 6490
 mirrors/metadata_test: Fail # Issue 6490
 mirrors/reflect_model_test: Fail # Issue 6490
 mirrors/reflect_runtime_type_test: Fail # Issue 6490
@@ -35,9 +36,6 @@
 mirrors/superclass_test: Fail # Issue 6490
 mirrors/to_string_test: Fail # Issue 6490
 
-[ $compiler == dart2js && $checked ]
-async/stream_event_transform_test: Fail # Issue 7733.
-
 [ $compiler == dart2js && $jscl ]
 async/future_test: Fail # Timer interface not supported; dartbug.com/7728.
 async/slow_consumer2_test: Fail # Timer interface not supported; dartbug.com/7728.
@@ -67,13 +65,8 @@
                                          # implement timer (currently only in d8)
 
 [ $compiler == dart2dart ]
-mirrors/metadata_test: Fail
-mirrors/mirrors_test: Fail              # Issue 10957
-mirrors/library_uri_package_test: Fail  # Issue 10957
+mirrors/*: Skip # http://dartbug.com/11511
 async/run_async6_test: Fail             # Issue 10957 - may be related to issue 10910
-mirrors/reflect_model_test: Fail # http://dartbug.com/11219
-mirrors/disable_tree_shaking_test: Fail
-mirrors/to_string_test: Fail
 
 [ $compiler == dart2dart && $minified ]
 json/json_test: Fail                           # Issue 10961
@@ -81,9 +74,6 @@
 typed_data/float32x4_list_test: Fail           # Issue 10961
 typed_data/float32x4_unbox_phi_test: Fail      # Issue 10961
 typed_data/float32x4_unbox_regress_test: Fail  # Issue 10961
-mirrors/reflect_runtime_type_test: Fail
-mirrors/reflect_uninstantiated_class_test: Fail
-
 
 [ $runtime == ff ]
 # FF setTimeout can fire early: https://bugzilla.mozilla.org/show_bug.cgi?id=291386
diff --git a/tests/lib/mirrors/constructors_test.dart b/tests/lib/mirrors/constructors_test.dart
new file mode 100644
index 0000000..1a717a7
--- /dev/null
+++ b/tests/lib/mirrors/constructors_test.dart
@@ -0,0 +1,48 @@
+// 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 test.constructors_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'reflect_model_test.dart';
+
+class Foo {
+}
+
+class Bar {
+  Bar();
+}
+
+class Baz {
+  Baz.named();
+}
+
+class Biz {
+  Biz();
+  Biz.named();
+}
+
+main() {
+  MirrorSystem mirrors = currentMirrorSystem();
+  ClassMirror fooMirror = reflectClass(Foo);
+  Map<Symbol, MethodMirror> fooConstructors = fooMirror.constructors;
+  ClassMirror barMirror = reflectClass(Bar);
+  Map<Symbol, MethodMirror> barConstructors = barMirror.constructors;
+  ClassMirror bazMirror = reflectClass(Baz);
+  Map<Symbol, MethodMirror> bazConstructors = bazMirror.constructors;
+  ClassMirror bizMirror = reflectClass(Biz);
+  Map<Symbol, MethodMirror> bizConstructors = bizMirror.constructors;
+
+  expect('{Foo: Method(s(Foo) in s(Foo), constructor)}', fooConstructors);
+  expect('{Bar: Method(s(Bar) in s(Bar), constructor)}', barConstructors);
+  expect('{Baz.named: Method(s(Baz.named) in s(Baz), constructor)}',
+         bazConstructors);
+  expect('{Biz: Method(s(Biz) in s(Biz), constructor),'
+         ' Biz.named: Method(s(Biz.named) in s(Biz), constructor)}',
+         bizConstructors);
+  print(bizConstructors);
+}
diff --git a/tests/lib/mirrors/get_symbol_name_no_such_method_test.dart b/tests/lib/mirrors/get_symbol_name_no_such_method_test.dart
index 7210d98..1b60ae5 100644
--- a/tests/lib/mirrors/get_symbol_name_no_such_method_test.dart
+++ b/tests/lib/mirrors/get_symbol_name_no_such_method_test.dart
@@ -24,14 +24,12 @@
   expect('foo', foo.foo);
   expect('foo', foo.foo());
   expect('foo', foo.foo(null));
-  // TODO(ahe): Why does the following not work in dart2js/minified.
-  // expect('foo', foo.foo(null, null));
+  expect('foo', foo.foo(null, null));
   expect('foo', foo.foo(a: null, b: null));
 
   expect('baz', foo.baz);
   expect('baz', foo.baz());
   expect('baz', foo.baz(null));
-  // TODO(ahe): Why does the following not work in dart2js/minified.
-  // expect('baz', foo.baz(null, null));
+  expect('baz', foo.baz(null, null));
   expect('baz', foo.baz(a: null, b: null));
 }
diff --git a/tests/lib/mirrors/libraries_test.dart b/tests/lib/mirrors/libraries_test.dart
new file mode 100644
index 0000000..70a5e58
--- /dev/null
+++ b/tests/lib/mirrors/libraries_test.dart
@@ -0,0 +1,29 @@
+// 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 test.libraries_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+main() {
+  MirrorSystem mirrors = currentMirrorSystem();
+  Expect.isNotNull(mirrors, 'mirrors is null');
+
+  Map<Uri, LibraryMirror> libraries = mirrors.libraries;
+  Expect.isNotNull(libraries, 'libraries is null');
+
+  LibraryMirror mirrorsLibrary = libraries[Uri.parse('dart:mirrors')];
+  Expect.isNotNull(mirrorsLibrary, 'mirrorsLibrary is null');
+
+  print(mirrorsLibrary.classes);
+  ClassMirror cls = mirrorsLibrary.classes[const Symbol('LibraryMirror')];
+  Expect.isNotNull(cls, 'cls is null');
+
+  Expect.equals(const Symbol('dart.mirrors.LibraryMirror'), cls.qualifiedName);
+  // TODO(ahe): Enable when VM implements equality of class mirrors:
+  // Expect.equals(reflectClass(LibraryMirror), cls);
+  print(mirrorsLibrary);
+}
diff --git a/tests/lib/mirrors/library_uri_io_test.dart b/tests/lib/mirrors/library_uri_io_test.dart
index add283d..1ee7b4c 100644
--- a/tests/lib/mirrors/library_uri_io_test.dart
+++ b/tests/lib/mirrors/library_uri_io_test.dart
@@ -27,7 +27,7 @@
     Uri cwd = new Uri(
         scheme: 'file',
         path: appendSlash(new Path(new File('.').fullPathSync()).toString()));
-    Uri uri = cwd.resolve(new Path(new Options().script).toString());
+    Uri uri = cwd.resolve(new Path(Platform.script).toString());
     testLibraryUri(new Class(), uri);
   });
 }
diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart
index b044283..13f8587 100644
--- a/tests/lib/mirrors/mirrors_test.dart
+++ b/tests/lib/mirrors/mirrors_test.dart
@@ -208,7 +208,6 @@
   if (!isMinified) // TODO(ahe): Remove this line.
   test("Test field access", () { testFieldAccess(mirrors); });
   test("Test closure mirrors", () { testClosureMirrors(mirrors); });
-  if (!isMinified) // TODO(ahe): Remove this line.
   test("Test invoke constructor", () { testInvokeConstructor(mirrors); });
   test("Test current library uri", () {
     testLibraryUri(new Class(),
diff --git a/tests/lib/mirrors/reflect_model_test.dart b/tests/lib/mirrors/reflect_model_test.dart
index e96124a..567651c 100644
--- a/tests/lib/mirrors/reflect_model_test.dart
+++ b/tests/lib/mirrors/reflect_model_test.dart
@@ -55,6 +55,7 @@
   if (method.isStatic) buffer.write(', static');
   if (method.isGetter) buffer.write(', getter');
   if (method.isSetter) buffer.write(', setter');
+  if (method.isConstructor) buffer.write(', constructor');
   return (buffer..write(')')).toString();
 }
 
diff --git a/tests/standalone/53bit_overflow_test.dart b/tests/standalone/53bit_overflow_test.dart
index 256e66a..3bbc6e3 100644
--- a/tests/standalone/53bit_overflow_test.dart
+++ b/tests/standalone/53bit_overflow_test.dart
@@ -54,6 +54,9 @@
   return min_literal;
 }
 
+// We don't test for the _FiftyThreeBitOverflowError since it's not visible.
+// It's should not be visible since it doesn't exist on dart2js.
+bool is53BitError(e) => e is Error && "$e".startsWith("53-bit Overflow:");
 
 main() {
   Expect.equals(0xFFFFFFFFFFFFF, max_literal());
@@ -61,20 +64,20 @@
 
   // Run the tests once before optimizations.
   dti_arg = 1.9e16;
-  Expect.throws(double_to_int, (e) => e is FiftyThreeBitOverflowError);
+  Expect.throws(double_to_int, is53BitError);
 
   ia_arg1 = (1 << 51);
   ia_arg2 = (1 << 51);
-  Expect.throws(integer_add, (e) => e is FiftyThreeBitOverflowError);
+  Expect.throws(integer_add, is53BitError);
 
   n_arg = -0xFFFFFFFFFFFFF - 1;
-  Expect.throws(negate, (e) => e is FiftyThreeBitOverflowError);
+  Expect.throws(negate, is53BitError);
 
   is_arg = (1 << 51);
-  Expect.throws(integer_shift, (e) => e is FiftyThreeBitOverflowError);
+  Expect.throws(integer_shift, is53BitError);
 
-  Expect.throws(max_add_throws, (e) => e is FiftyThreeBitOverflowError);
-  Expect.throws(min_sub_throws, (e) => e is FiftyThreeBitOverflowError);
+  Expect.throws(max_add_throws, is53BitError);
+  Expect.throws(min_sub_throws, is53BitError);
 
   for (int i = 0; i < 20; i++) {
     dti_arg = i.toDouble();
@@ -96,20 +99,20 @@
     Expect.equals(i << 1, f());
   }
 
-  // The optimized functions should now deoptimize and throw the error.
+   // The optimized functions should now deoptimize and throw the error.
   dti_arg = 1.9e16;
-  Expect.throws(double_to_int, (e) => e is FiftyThreeBitOverflowError);
+  Expect.throws(double_to_int, is53BitError);
 
   ia_arg1 = (1 << 51);
   ia_arg2 = (1 << 51);
-  Expect.throws(integer_add, (e) => e is FiftyThreeBitOverflowError);
+  Expect.throws(integer_add, is53BitError);
 
   n_arg = -0xFFFFFFFFFFFFF - 1;
-  Expect.throws(negate, (e) => e is FiftyThreeBitOverflowError);
+  Expect.throws(negate, is53BitError);
 
   is_arg = (1 << 51);
-  Expect.throws(integer_shift, (e) => e is FiftyThreeBitOverflowError);
+  Expect.throws(integer_shift, is53BitError);
 
-  Expect.throws(max_add_throws, (e) => e is FiftyThreeBitOverflowError);
-  Expect.throws(min_sub_throws, (e) => e is FiftyThreeBitOverflowError);
+  Expect.throws(max_add_throws, is53BitError);
+  Expect.throws(min_sub_throws, is53BitError);
 }
diff --git a/tests/standalone/coverage_test.dart b/tests/standalone/coverage_test.dart
index b5a236e..b48d99b 100644
--- a/tests/standalone/coverage_test.dart
+++ b/tests/standalone/coverage_test.dart
@@ -47,11 +47,9 @@
 }
 
 void main() {
-  var options = new Options();
-
   // Compute paths for coverage tool and coverage target relative
   // the the path of this script.
-  var scriptPath = new Path(options.script).directoryPath;
+  var scriptPath = new Path(Platform.script).directoryPath;
   var toolPath = scriptPath.join(new Path(coverageToolScript)).canonicalize();
   targPath = scriptPath.join(new Path(coverageTargetScript)).canonicalize();
 
@@ -62,7 +60,7 @@
                       toolPath.toNativePath(),
                       targPath.toNativePath() ];
 
-  Process.start(options.executable, processOpts).then((Process process) {
+  Process.start(Platform.executable, processOpts).then((Process process) {
     coverageToolProcess = process;
     coverageToolProcess.stdin.close();
     var stdoutStringStream = coverageToolProcess.stdout
diff --git a/tests/standalone/debugger/breakpoint_resolved_test.dart b/tests/standalone/debugger/breakpoint_resolved_test.dart
index 9fef0df..4cf748b 100644
--- a/tests/standalone/debugger/breakpoint_resolved_test.dart
+++ b/tests/standalone/debugger/breakpoint_resolved_test.dart
@@ -6,14 +6,14 @@
 
 main() {
   if (RunScript(testScript)) return;
-  
+
   bar();
-  
+
   print("Hello from debuggee");
 }
 
 bar() {
-  
+
   print("bar");
 }
 
diff --git a/tests/standalone/debugger/debug_lib.dart b/tests/standalone/debugger/debug_lib.dart
index 8532ac0..34500ba 100644
--- a/tests/standalone/debugger/debug_lib.dart
+++ b/tests/standalone/debugger/debug_lib.dart
@@ -231,6 +231,74 @@
 }
 
 
+class LocalsMatcher extends Command {
+  Map locals = {};
+  
+  LocalsMatcher(this.locals) {
+    template = {"id": 0, "command": "getStackTrace", "params": {"isolateId": 0}};
+  }
+
+  void matchResponse(Debugger debugger) {
+    super.matchResponse(debugger);
+    
+    List frames = getJsonValue(debugger.currentMessage, "result:callFrames");
+    assert(frames != null);
+    
+    String functionName = frames[0]['functionName'];
+    List localsList = frames[0]['locals'];
+    Map reportedLocals = {};
+    localsList.forEach((local) => reportedLocals[local['name']] = local['value']);    
+    for (String key in locals.keys) {
+      if (reportedLocals[key] == null) {
+        debugger.error("Error in $functionName(): no value reported for local "
+            "variable $key");
+        return;
+      }
+      String expected = locals[key];
+      String actual = reportedLocals[key]['text'];
+      if (expected != actual) {
+        debugger.error("Error in $functionName(): got '$actual' for local "
+            "variable $key, but expected '$expected'");
+        return;
+      }
+    }
+  }
+}
+
+
+MatchLocals(Map localValues) {
+  return new LocalsMatcher(localValues);
+}
+
+
+class EventMatcher {
+  String eventName;
+  Map params;
+  
+  EventMatcher(this.eventName, this.params);
+  
+  void matchEvent(Debugger debugger) {
+    for (Event event in debugger.events) {
+      if (event.name == eventName) {
+        if (params == null || matchMaps(params, event.params)) {
+          // Remove the matched event, so we don't match against it in the future.
+          debugger.events.remove(event);
+          return;
+        }
+      }
+    }
+    
+    String msg = params == null ? '' : params.toString();
+    debugger.error("Error: could not match event $eventName $msg");
+  }
+}
+
+
+ExpectEvent(String eventName, [Map params]) {
+  return new EventMatcher(eventName, params);
+}
+
+
 class RunCommand extends Command {
   RunCommand.resume() {
     template = {"id": 0, "command": "resume", "params": {"isolateId": 0}};
@@ -276,6 +344,16 @@
 
 SetBreakpoint(int line) => new SetBreakpointCommand(line);
 
+class Event {
+  String name;
+  Map params;
+  
+  Event(Map json) {
+    name = json['event'];
+    params = json['params'];
+  }
+}
+
 
 // A debug script is a list of Command objects.
 class DebugScript {
@@ -285,6 +363,7 @@
     entries.add(MatchFrame(0, "main"));
   }
   bool get isEmpty => entries.isEmpty;
+  bool get isNextEventMatcher => !isEmpty && currentEntry is EventMatcher;
   get currentEntry => entries.last;
   advance() => entries.removeLast();
   add(entry) => entries.add(entry);
@@ -301,6 +380,7 @@
   int seqNr = 0;  // Sequence number of next debugger command message.
   Command lastCommand = null;  // Most recent command sent to target.
   List<String> errors = new List();
+  List<Event> events = new List();
   bool cleanupDone = false;
 
   // Data collected from debug target.
@@ -334,6 +414,8 @@
 
   // Handle debugger events, updating the debugger state.
   void handleEvent(Map<String,dynamic> msg) {
+    events.add(new Event(msg));
+    
     if (msg["event"] == "isolate") {
       if (msg["params"]["reason"] == "created") {
         isolateId = msg["params"]["id"];
@@ -388,6 +470,12 @@
   // Send next debugger command in the script, if a response
   // form the last command has been received and processed.
   void sendNextCommand() {
+    while (script.isNextEventMatcher) {
+      EventMatcher matcher = script.currentEntry;
+      script.advance();      
+      matcher.matchEvent(this);
+    }
+    
     if (lastCommand == null) {
       if (script.currentEntry is Command) {
         script.currentEntry.send(this);
@@ -521,11 +609,11 @@
 
   // Port number 0 means debug target picks a free port dynamically.
   var targetOpts = [ "--debug:0" ];
-  targetOpts.add(options.script);
+  targetOpts.add(Platform.script);
   targetOpts.add("--debuggee");
   print('args: ${targetOpts.join(" ")}');
 
-  Process.start(options.executable, targetOpts).then((Process process) {
+  Process.start(Platform.executable, targetOpts).then((Process process) {
     print("Debug target process started, pid ${process.pid}.");
     process.stdin.close();
     var debugger = new Debugger(process, new DebugScript(script));
diff --git a/tests/standalone/debugger/tostring_throws_test.dart b/tests/standalone/debugger/tostring_throws_test.dart
index f25050d..03fd322 100644
--- a/tests/standalone/debugger/tostring_throws_test.dart
+++ b/tests/standalone/debugger/tostring_throws_test.dart
@@ -6,9 +6,9 @@
 
 main() {
   if (RunScript(testScript)) return;
-  
+
   Foo foo = new Foo();
-  
+
   print("Hello from debuggee");
 }
 
diff --git a/tests/standalone/http_launch_test.dart b/tests/standalone/http_launch_test.dart
index 06b647e..6f8021d 100644
--- a/tests/standalone/http_launch_test.dart
+++ b/tests/standalone/http_launch_test.dart
@@ -18,8 +18,8 @@
 import 'dart:io';
 import 'package:expect/expect.dart';
 
-String pathToExecutable = new Options().executable;
-String pathOfData = new File(new Options().script).directory.path +
+String pathToExecutable = Platform.executable;
+String pathOfData = new File(Platform.script).directory.path +
                     '/http_launch_data';
 int port;
 
diff --git a/tests/standalone/io/dart_std_io_pipe_test.dart b/tests/standalone/io/dart_std_io_pipe_test.dart
index e3dfec0..cc37115 100644
--- a/tests/standalone/io/dart_std_io_pipe_test.dart
+++ b/tests/standalone/io/dart_std_io_pipe_test.dart
@@ -39,7 +39,7 @@
   String pipeOutFile = "${dir.path}/pipe";
   if (devNull) pipeOutFile = "/dev/null";
   String redirectOutFile = "${dir.path}/redirect";
-  String executable = new Options().executable;
+  String executable = Platform.executable;
   List args =
       [executable,
        dartScript,
diff --git a/tests/standalone/io/directory_list_pause_test.dart b/tests/standalone/io/directory_list_pause_test.dart
index 178f59f..081b406 100644
--- a/tests/standalone/io/directory_list_pause_test.dart
+++ b/tests/standalone/io/directory_list_pause_test.dart
@@ -10,31 +10,34 @@
 
 void testPauseList() {
   var keepAlive = new ReceivePort();
+  // TOTAL should be bigger the our directory listing buffer.
+  const int TOTAL = 128;
   new Directory("").createTemp().then((d) {
-    // Linux reads 2K at a time, so be sure to be >>.
-    int total = 4 * 1024 + 1;
-    for (int i = 0; i < total; i++) {
-      new File("${d.path}/$i").createSync();
+    for (int i = 0; i < TOTAL; i++) {
+      new Directory("${d.path}/$i").createSync();
+      new File("${d.path}/$i/file").createSync();
     }
     bool first = true;
     var subscription;
     int count = 0;
-    subscription = d.list().listen((file) {
-      if (first) {
-        first = false;
-        subscription.pause();
-        Timer.run(() {
-          for (int i = 0; i < total; i++) {
-            new File("${d.path}/$i").deleteSync();
-          }
-          subscription.resume();
-        });
+    subscription = d.list(recursive: true).listen((file) {
+      if (file is File) {
+        if (first) {
+          first = false;
+          subscription.pause();
+          Timer.run(() {
+            for (int i = 0; i < TOTAL; i++) {
+              new File("${d.path}/$i/file").deleteSync();
+            }
+            subscription.resume();
+          });
+        }
+        count++;
       }
-      count++;
     }, onDone: () {
-      Expect.notEquals(total, count);
-      keepAlive.close();
-      d.delete().then((ignore) => keepAlive.close());
+      Expect.notEquals(TOTAL, count);
+      Expect.isTrue(count > 0);
+      d.delete(recursive: true).then((ignore) => keepAlive.close());
     });
   });
 }
diff --git a/tests/standalone/io/directory_test.dart b/tests/standalone/io/directory_test.dart
index 6592281..f9927d3 100644
--- a/tests/standalone/io/directory_test.dart
+++ b/tests/standalone/io/directory_test.dart
@@ -85,6 +85,24 @@
     Expect.isFalse(listedFile);
   }
 
+  static void testListingTailingPaths() {
+    Directory directory = new Directory("").createTempSync();
+    Directory subDirectory = new Directory("${directory.path}/subdir/");
+    subDirectory.createSync();
+    File f = new File('${subDirectory.path}/file.txt');
+    f.createSync();
+
+    void test(entry) {
+      Expect.isFalse(entry.path.contains(new RegExp('[\\/][\\/]')));
+    }
+
+    subDirectory.listSync().forEach(test);
+
+    subDirectory.list().listen(test, onDone: () {
+      directory.deleteSync(recursive: true);
+    });
+  }
+
   static void testListNonExistent() {
     setupListerHandlers(Stream<FileSystemEntity> stream) {
       stream.listen(
@@ -397,6 +415,7 @@
 
   static void testMain() {
     testListing();
+    testListingTailingPaths();
     testListNonExistent();
     testListTooLongName();
     testDeleteNonExistent();
diff --git a/tests/standalone/io/file_read_special_device_test.dart b/tests/standalone/io/file_read_special_device_test.dart
index c32db08..d9880f3 100644
--- a/tests/standalone/io/file_read_special_device_test.dart
+++ b/tests/standalone/io/file_read_special_device_test.dart
@@ -6,10 +6,9 @@
 import 'dart:io';
 
 void openAndWriteScript(String script) {
-  var options = new Options();
-  var dir = new Path(options.script).directoryPath;
+  var dir = new Path(Platform.script).directoryPath;
   script = "$dir/$script";
-  var executable = options.executable;
+  var executable = Platform.executable;
   var file = script;  // Use script as file.
   Process.start("bash", ["-c", "$executable $script < $file"]).then((process) {
     process.exitCode
diff --git a/tests/standalone/io/file_read_stdio_script.dart b/tests/standalone/io/file_read_stdio_script.dart
index b2043ff..966d914 100644
--- a/tests/standalone/io/file_read_stdio_script.dart
+++ b/tests/standalone/io/file_read_stdio_script.dart
@@ -5,7 +5,7 @@
 import 'dart:io';
 
 void main() {
-  var expected = new File(new Options().script).readAsStringSync();
+  var expected = new File(Platform.script).readAsStringSync();
   var stdin = new File('/dev/fd/0').readAsStringSync();
   if (expected != stdin) {
     throw "stdin not equal expected file";
diff --git a/tests/standalone/io/file_test.dart b/tests/standalone/io/file_test.dart
index c34b823..b159031 100644
--- a/tests/standalone/io/file_test.dart
+++ b/tests/standalone/io/file_test.dart
@@ -1106,7 +1106,7 @@
 
   static void testLastModified() {
     var port = new ReceivePort();
-    new File(new Options().executable).lastModified().then((modified) {
+    new File(Platform.executable).lastModified().then((modified) {
       Expect.isTrue(modified is DateTime);
       Expect.isTrue(modified.isBefore(new DateTime.now()));
       port.close();
@@ -1114,7 +1114,7 @@
   }
 
   static void testLastModifiedSync() {
-    var modified = new File(new Options().executable).lastModifiedSync();
+    var modified = new File(Platform.executable).lastModifiedSync();
     Expect.isTrue(modified is DateTime);
     Expect.isTrue(modified.isBefore(new DateTime.now()));
   }
diff --git a/tests/standalone/io/http_proxy_test.dart b/tests/standalone/io/http_proxy_test.dart
index 5e7bfe1..70e06b6 100644
--- a/tests/standalone/io/http_proxy_test.dart
+++ b/tests/standalone/io/http_proxy_test.dart
@@ -746,7 +746,7 @@
 
 void InitializeSSL() {
   var testPkcertDatabase =
-      new Path(new Options().script).directoryPath.append('pkcert/');
+      new Path(Platform.script).directoryPath.append('pkcert/');
   SecureSocket.initialize(database: testPkcertDatabase.toNativePath(),
                           password: 'dartdart');
 }
diff --git a/tests/standalone/io/http_server_early_client_close2_test.dart b/tests/standalone/io/http_server_early_client_close2_test.dart
index 5f695de..0f3f73b 100644
--- a/tests/standalone/io/http_server_early_client_close2_test.dart
+++ b/tests/standalone/io/http_server_early_client_close2_test.dart
@@ -16,7 +16,7 @@
   HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen(
       (request) {
-        String name = new Options().script;
+        String name = Platform.script;
         new File(name).openRead().pipe(request.response)
             .catchError((e) { /* ignore */ });
       });
diff --git a/tests/standalone/io/http_server_early_client_close_test.dart b/tests/standalone/io/http_server_early_client_close_test.dart
index 5062a70..4b481db 100644
--- a/tests/standalone/io/http_server_early_client_close_test.dart
+++ b/tests/standalone/io/http_server_early_client_close_test.dart
@@ -118,7 +118,7 @@
   HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen(
       (request) {
-        String name = new Options().script;
+        String name = Platform.script;
         new File(name).openRead().pipe(request.response)
             .catchError((e) { /* ignore */ });
       });
diff --git a/tests/standalone/io/http_server_response_test.dart b/tests/standalone/io/http_server_response_test.dart
index 307cec1..e1deb8d 100644
--- a/tests/standalone/io/http_server_response_test.dart
+++ b/tests/standalone/io/http_server_response_test.dart
@@ -80,10 +80,10 @@
 
 
 void testResponseAddStream() {
-  int bytes = new File(new Options().script).lengthSync();
+  int bytes = new File(Platform.script).lengthSync();
 
   testServerRequest((server, request) {
-    request.response.addStream(new File(new Options().script).openRead())
+    request.response.addStream(new File(Platform.script).openRead())
         .then((response) {
           response.close();
           response.done.then((_) => server.close());
@@ -91,9 +91,9 @@
   }, bytes: bytes);
 
   testServerRequest((server, request) {
-    request.response.addStream(new File(new Options().script).openRead())
+    request.response.addStream(new File(Platform.script).openRead())
         .then((response) {
-          request.response.addStream(new File(new Options().script).openRead())
+          request.response.addStream(new File(Platform.script).openRead())
               .then((response) {
                 response.close();
                 response.done.then((_) => server.close());
@@ -129,7 +129,7 @@
 
 void testResponseAddStreamClosed() {
   testServerRequest((server, request) {
-    request.response.addStream(new File(new Options().script).openRead())
+    request.response.addStream(new File(Platform.script).openRead())
         .then((response) {
           response.close();
           response.done.then((_) => server.close());
@@ -139,7 +139,7 @@
   testServerRequest((server, request) {
     int count = 0;
     write() {
-      request.response.addStream(new File(new Options().script).openRead())
+      request.response.addStream(new File(Platform.script).openRead())
           .then((response) {
             request.response.write("sync data");
             count++;
@@ -158,14 +158,14 @@
 
 void testResponseAddClosed() {
   testServerRequest((server, request) {
-    request.response.add(new File(new Options().script).readAsBytesSync());
+    request.response.add(new File(Platform.script).readAsBytesSync());
     request.response.close();
     request.response.done.then((_) => server.close());
   }, closeClient: true);
 
   testServerRequest((server, request) {
     for (int i = 0; i < 1000; i++) {
-      request.response.add(new File(new Options().script).readAsBytesSync());
+      request.response.add(new File(Platform.script).readAsBytesSync());
     }
     request.response.close();
     request.response.done.then((_) => server.close());
@@ -174,7 +174,7 @@
   testServerRequest((server, request) {
     int count = 0;
     write() {
-      request.response.add(new File(new Options().script).readAsBytesSync());
+      request.response.add(new File(Platform.script).readAsBytesSync());
       Timer.run(() {
         count++;
         if (count < 1000) {
diff --git a/tests/standalone/io/https_client_certificate_test.dart b/tests/standalone/io/https_client_certificate_test.dart
index 141470a..847b19a 100644
--- a/tests/standalone/io/https_client_certificate_test.dart
+++ b/tests/standalone/io/https_client_certificate_test.dart
@@ -45,7 +45,7 @@
 
 void InitializeSSL() {
   var testPkcertDatabase =
-      new Path(new Options().script).directoryPath.append('pkcert/');
+      new Path(Platform.script).directoryPath.append('pkcert/');
   SecureSocket.initialize(database: testPkcertDatabase.toNativePath(),
                           password: 'dartdart');
 }
diff --git a/tests/standalone/io/https_server_test.dart b/tests/standalone/io/https_server_test.dart
index 2e0b2a0..6ca31bc 100644
--- a/tests/standalone/io/https_server_test.dart
+++ b/tests/standalone/io/https_server_test.dart
@@ -59,7 +59,7 @@
 
 void InitializeSSL() {
   var testPkcertDatabase =
-      new Path(new Options().script).directoryPath.append('pkcert/');
+      new Path(Platform.script).directoryPath.append('pkcert/');
   SecureSocket.initialize(database: testPkcertDatabase.toNativePath(),
                           password: 'dartdart');
 }
diff --git a/tests/standalone/io/internet_address_test.dart b/tests/standalone/io/internet_address_test.dart
index 67216d4..22c4a66 100644
--- a/tests/standalone/io/internet_address_test.dart
+++ b/tests/standalone/io/internet_address_test.dart
@@ -6,7 +6,7 @@
 
 import "package:expect/expect.dart";
 
-void test() {
+void testDefaultAddresses() {
   var loopback4 = InternetAddress.LOOPBACK_IP_V4;
   Expect.isNotNull(loopback4);
   Expect.equals(InternetAddressType.IP_V4, loopback4.type);
@@ -32,6 +32,23 @@
   Expect.equals("::", any6.address);
 }
 
+void testReverseLookup() {
+  InternetAddress.lookup('localhost').then((addrs) {
+    addrs.first.reverse().then((addr) {
+      Expect.isNotNull(addr.host);
+    });
+  });
+
+  InternetAddress.lookup('127.0.0.1').then((addrs) {
+    Expect.equals('127.0.0.1', addrs.first.host);
+    addrs.first.reverse().then((addr) {
+      Expect.isNotNull(addr.host);
+      Expect.notEquals('127.0.0.1', addr.host);
+    });
+  });
+}
+
 void main() {
-  test();
+  testDefaultAddresses();
+  testReverseLookup();
 }
diff --git a/tests/standalone/io/link_test.dart b/tests/standalone/io/link_test.dart
index 0562cb3b..7bef4c5 100644
--- a/tests/standalone/io/link_test.dart
+++ b/tests/standalone/io/link_test.dart
@@ -173,7 +173,15 @@
     new Directory.fromPath(base).delete(recursive: true));
 }
 
+void testLinkErrorSync() {
+  Expect.throws(() =>
+      new Link('some-dir-that-doent exist/some link file/bla/fisk').createSync(
+          'bla bla bla/b lalal/blfir/sdfred/es'),
+      (e) => e is LinkException);
+}
+
 main() {
   testCreateSync();
   testCreateLoopingLink();
+  testLinkErrorSync();
 }
diff --git a/tests/standalone/io/network_interface_test.dart b/tests/standalone/io/network_interface_test.dart
new file mode 100644
index 0000000..ee6a25e
--- /dev/null
+++ b/tests/standalone/io/network_interface_test.dart
@@ -0,0 +1,39 @@
+// 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 'dart:io';
+
+import "package:expect/expect.dart";
+
+
+void testListLoopback() {
+  NetworkInterface.list(includeLoopback: false).then((list) {
+    for (var i in list) {
+      for (var a in i.addresses) {
+        Expect.isFalse(a.isLoopback);
+      }
+    }
+  });
+
+  NetworkInterface.list(includeLoopback: true).then((list) {
+    Expect.isTrue(list.any((i) => i.addresses.any((a) => a.isLoopback)));
+  });
+}
+
+
+void testListLinkLocal() {
+  NetworkInterface.list(includeLinkLocal: false).then((list) {
+    for (var i in list) {
+      for (var a in i.addresses) {
+        Expect.isFalse(a.isLinkLocal);
+      }
+    }
+  });
+}
+
+
+void main() {
+  testListLoopback();
+  testListLinkLocal();
+}
diff --git a/tests/standalone/io/options_test.dart b/tests/standalone/io/options_test.dart
index cad7d91..9f61e35 100644
--- a/tests/standalone/io/options_test.dart
+++ b/tests/standalone/io/options_test.dart
@@ -16,9 +16,6 @@
   Expect.equals(10, int.parse(opts.arguments[0]));
   Expect.equals("options_test", opts.arguments[1]);
   Expect.equals(20, int.parse(opts.arguments[2]));
-  Expect.isTrue(opts.executable.contains('dart'));
-  Expect.isTrue(opts.script.replaceAll('\\', '/').
-                endsWith('tests/standalone/io/options_test.dart'));
 
   // Now add an additional argument.
   opts.arguments.add("Fourth");
diff --git a/tests/standalone/io/platform_test.dart b/tests/standalone/io/platform_test.dart
index 4a42683a..ce6e977 100644
--- a/tests/standalone/io/platform_test.dart
+++ b/tests/standalone/io/platform_test.dart
@@ -10,10 +10,17 @@
   var os = Platform.operatingSystem;
   Expect.isTrue(os == "android" || os == "linux" || os == "macos" ||
       os == "windows");
+  Expect.equals(Platform.isLinux, Platform.operatingSystem == "linux");
+  Expect.equals(Platform.isMacOS, Platform.operatingSystem == "macos");
+  Expect.equals(Platform.isWindows, Platform.operatingSystem == "windows");
+  Expect.equals(Platform.isAndroid, Platform.operatingSystem == "android");
   var sep = Platform.pathSeparator;
   Expect.isTrue(sep == '/' || (os == 'windows' && sep == '\\'));
   var hostname = Platform.localHostname;
   Expect.isTrue(hostname is String && hostname != "");
   var environment = Platform.environment;
   Expect.isTrue(environment is Map<String, String>);
+  Expect.isTrue(Platform.executable.contains('dart'));
+  Expect.isTrue(Platform.script.replaceAll('\\', '/').
+                endsWith('tests/standalone/io/platform_test.dart'));
 }
diff --git a/tests/standalone/io/process_broken_pipe_test.dart b/tests/standalone/io/process_broken_pipe_test.dart
index 01451bf..7791fd4 100644
--- a/tests/standalone/io/process_broken_pipe_test.dart
+++ b/tests/standalone/io/process_broken_pipe_test.dart
@@ -12,7 +12,7 @@
 
 main() {
   // Running dart without arguments makes it close right away.
-  var future = Process.start(new Options().executable, []);
+  var future = Process.start(Platform.executable, []);
   future.then((process) {
     process.stdin.done.catchError((e) {
       // Accept errors on stdin.
diff --git a/tests/standalone/io/process_check_arguments_script.dart b/tests/standalone/io/process_check_arguments_script.dart
index 4e933b9..183beaf 100644
--- a/tests/standalone/io/process_check_arguments_script.dart
+++ b/tests/standalone/io/process_check_arguments_script.dart
@@ -23,7 +23,8 @@
 
 main() {
   var options = new Options();
-  Expect.isTrue(options.script.endsWith('process_check_arguments_script.dart'));
+  Expect.isTrue(Platform.script.endsWith(
+      'process_check_arguments_script.dart'));
   var expected_num_args = int.parse(options.arguments[0]);
   var contains_quote = int.parse(options.arguments[1]);
   Expect.equals(expected_num_args, options.arguments.length);
diff --git a/tests/standalone/io/process_check_arguments_test.dart b/tests/standalone/io/process_check_arguments_test.dart
index 68da4a2..da5324e 100644
--- a/tests/standalone/io/process_check_arguments_test.dart
+++ b/tests/standalone/io/process_check_arguments_test.dart
@@ -7,7 +7,7 @@
 import "process_test_util.dart";
 
 test(args) {
-  var future = Process.start(new Options().executable, args);
+  var future = Process.start(Platform.executable, args);
   future.then((process) {
     process.exitCode.then((exitCode) {
       Expect.equals(0, exitCode);
diff --git a/tests/standalone/io/process_environment_test.dart b/tests/standalone/io/process_environment_test.dart
index 24cc73d..cb60471 100644
--- a/tests/standalone/io/process_environment_test.dart
+++ b/tests/standalone/io/process_environment_test.dart
@@ -7,15 +7,16 @@
 import "dart:isolate";
 import "process_test_util.dart";
 
-runEnvironmentProcess(Map environment, name, callback) {
-  var dartExecutable = new Options().executable;
+runEnvironmentProcess(Map environment, name, includeParent, callback) {
+  var dartExecutable = Platform.executable;
   var printEnv = 'tests/standalone/io/print_env.dart';
   if (!new File(printEnv).existsSync()) {
     printEnv = '../$printEnv';
   }
   Process.run(dartExecutable,
               [printEnv, name],
-              environment: environment)
+              environment: environment,
+              includeParentEnvironment: includeParent)
       .then((result) {
         Expect.equals(0, result.exitCode);
         callback(result.stdout);
@@ -29,7 +30,7 @@
   // Check that some value in the environment stays the same when passed
   // to another process.
   for (var k in env.keys) {
-    runEnvironmentProcess(env, k, (output) {
+    runEnvironmentProcess({}, k, true, (output) {
       // Only check startsWith. The print statements will add
       // newlines at the end.
       Expect.isTrue(output.startsWith(env[k]));
@@ -39,7 +40,7 @@
       var name = 'MYENVVAR';
       while (env.containsKey(name)) name = '${name}_';
       copy[name] = 'value';
-      runEnvironmentProcess(copy, name, (output) {
+      runEnvironmentProcess(copy, name, true, (output) {
         Expect.isTrue(output.startsWith('value'));
         donePort.close();
       });
@@ -50,6 +51,18 @@
   }
 }
 
+testNoIncludeEnvironment() {
+  var donePort = new ReceivePort();
+  var env = Platform.environment;
+  Expect.isTrue(env.containsKey('PATH'));
+  env.remove('PATH');
+  runEnvironmentProcess(env, "PATH", false, (output) {
+    donePort.close();
+    Expect.isTrue(output.startsWith("null"));
+  });
+}
+
 main() {
   testEnvironment();
+  testNoIncludeEnvironment();
 }
diff --git a/tests/standalone/io/process_non_ascii_test.dart b/tests/standalone/io/process_non_ascii_test.dart
index bd8a683..f590cff 100644
--- a/tests/standalone/io/process_non_ascii_test.dart
+++ b/tests/standalone/io/process_non_ascii_test.dart
@@ -8,7 +8,7 @@
 
 main() {
   var port = new ReceivePort();
-  var executable = new File(new Options().executable).fullPathSync();
+  var executable = new File(Platform.executable).fullPathSync();
   var tempDir = new Directory('').createTempSync();
   var nonAsciiDir = new Directory('${tempDir.path}/æøå');
   nonAsciiDir.createSync();
diff --git a/tests/standalone/io/process_pid_test.dart b/tests/standalone/io/process_pid_test.dart
index c83a6d9..0016058 100644
--- a/tests/standalone/io/process_pid_test.dart
+++ b/tests/standalone/io/process_pid_test.dart
@@ -13,8 +13,8 @@
   var port = new ReceivePort();
   Expect.isTrue(pid > 0);
   var futures = [];
-  futures.add(Process.start(new Options().executable,['--version']));
-  futures.add(Process.run(new Options().executable,['--version']));
+  futures.add(Process.start(Platform.executable,['--version']));
+  futures.add(Process.run(Platform.executable,['--version']));
   Future.wait(futures).then((results) {
     Expect.isTrue(results[0].pid > 0);
     Expect.isTrue(results[1].pid > 0);
diff --git a/tests/standalone/io/process_run_output_test.dart b/tests/standalone/io/process_run_output_test.dart
index f8b06d4..efa9892 100644
--- a/tests/standalone/io/process_run_output_test.dart
+++ b/tests/standalone/io/process_run_output_test.dart
@@ -35,7 +35,7 @@
   }
 
   if (stream == 'stdout') {
-    Process.run(new Options().executable,
+    Process.run(Platform.executable,
                 [scriptFile, encoding, stream],
                 stdoutEncoding: enc). then((result) {
       Expect.equals(result.exitCode, 0);
@@ -43,7 +43,7 @@
       checkOutput(encoding, result.stdout);
     });
   } else {
-    Process.run(new Options().executable,
+    Process.run(Platform.executable,
                 [scriptFile, encoding, stream],
                 stderrEncoding: enc).then((result) {
       Expect.equals(result.exitCode, 0);
diff --git a/tests/standalone/io/process_set_exit_code_test.dart b/tests/standalone/io/process_set_exit_code_test.dart
index 1b0f767..39aa9b0 100644
--- a/tests/standalone/io/process_set_exit_code_test.dart
+++ b/tests/standalone/io/process_set_exit_code_test.dart
@@ -10,9 +10,8 @@
 import "dart:io";
 
 main() {
-  var options = new Options();
-  var executable = options.executable;
-  var script = options.script;
+  var executable = Platform.executable;
+  var script = Platform.script;
   var scriptDirectory = new Path(script).directoryPath;
   var exitCodeScript =
       scriptDirectory.append('process_set_exit_code_script.dart');
diff --git a/tests/standalone/io/process_shell_test.dart b/tests/standalone/io/process_shell_test.dart
index fd962d9..3d0f6a8 100644
--- a/tests/standalone/io/process_shell_test.dart
+++ b/tests/standalone/io/process_shell_test.dart
@@ -7,10 +7,9 @@
 
 void testRunShell() {
   test(args) {
-    var options = new Options();
-    var path = new Path(options.script);
+    var path = new Path(Platform.script);
     path = path.directoryPath.join(new Path("process_echo_util.dart"));
-    Process.run(options.executable,
+    Process.run(Platform.executable,
                 [path.toString()]..addAll(args),
                 runInShell: true)
         .then((result) {
@@ -44,8 +43,7 @@
 
 void testBadRunShell() {
   test(exe, [args = const []]) {
-    var options = new Options();
-    var path = new Path(options.script);
+    var path = new Path(Platform.script);
     path = path.directoryPath.join(new Path("process_echo_util.dart"));
     Process.run(exe, args, runInShell: true)
         .then((result) {
diff --git a/tests/standalone/io/process_stderr_test.dart b/tests/standalone/io/process_stderr_test.dart
index 8292b99..6c821d9 100644
--- a/tests/standalone/io/process_stderr_test.dart
+++ b/tests/standalone/io/process_stderr_test.dart
@@ -65,5 +65,5 @@
     scriptFile = new File("../tests/standalone/io/process_std_io_script.dart");
   }
   Expect.isTrue(scriptFile.existsSync());
-  test(Process.start(new Options().executable, [scriptFile.path, "1"]), 0);
+  test(Process.start(Platform.executable, [scriptFile.path, "1"]), 0);
 }
diff --git a/tests/standalone/io/process_stdin_transform_unsubscribe_test.dart b/tests/standalone/io/process_stdin_transform_unsubscribe_test.dart
index 94085a4..8b10d73 100644
--- a/tests/standalone/io/process_stdin_transform_unsubscribe_test.dart
+++ b/tests/standalone/io/process_stdin_transform_unsubscribe_test.dart
@@ -35,5 +35,5 @@
     scriptFile = new File("../tests/standalone/io/$scriptName");
   }
   Expect.isTrue(scriptFile.existsSync());
-  test(Process.start(new Options().executable, [scriptFile.path]), 0);
+  test(Process.start(Platform.executable, [scriptFile.path]), 0);
 }
diff --git a/tests/standalone/io/process_stdout_test.dart b/tests/standalone/io/process_stdout_test.dart
index 0bce7aa..8b117fe 100644
--- a/tests/standalone/io/process_stdout_test.dart
+++ b/tests/standalone/io/process_stdout_test.dart
@@ -65,5 +65,5 @@
     scriptFile = new File("../tests/standalone/io/process_std_io_script.dart");
   }
   Expect.isTrue(scriptFile.existsSync());
-  test(Process.start(new Options().executable, [scriptFile.path, "0"]), 0);
+  test(Process.start(Platform.executable, [scriptFile.path, "0"]), 0);
 }
diff --git a/tests/standalone/io/process_test_util.dart b/tests/standalone/io/process_test_util.dart
index f60c239..36325b1 100644
--- a/tests/standalone/io/process_test_util.dart
+++ b/tests/standalone/io/process_test_util.dart
@@ -14,7 +14,7 @@
 
 String getProcessTestFileName() {
   var extension = getPlatformExecutableExtension();
-  var executable = new Options().executable;
+  var executable = Platform.executable;
   var dirIndex = executable.lastIndexOf('dart$extension');
   var buffer = new StringBuffer(executable.substring(0, dirIndex));
   buffer.write('process_test$extension');
diff --git a/tests/standalone/io/raw_secure_server_closing_test.dart b/tests/standalone/io/raw_secure_server_closing_test.dart
index c1b7ddc..a629d45 100644
--- a/tests/standalone/io/raw_secure_server_closing_test.dart
+++ b/tests/standalone/io/raw_secure_server_closing_test.dart
@@ -143,7 +143,7 @@
 
 
 main() {
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart',
diff --git a/tests/standalone/io/raw_secure_server_socket_argument_test.dart b/tests/standalone/io/raw_secure_server_socket_argument_test.dart
index 6c78cbc..ee35920 100644
--- a/tests/standalone/io/raw_secure_server_socket_argument_test.dart
+++ b/tests/standalone/io/raw_secure_server_socket_argument_test.dart
@@ -17,17 +17,44 @@
 
 
 void testArguments() {
+  bool isArgOrTypeError(e) => e is ArgumentError || e is TypeError;
   Expect.throws(() =>
-      RawSecureServerSocket.bind(SERVER_ADDRESS, 65536, 5, CERTIFICATE));
+                RawSecureServerSocket.bind(SERVER_ADDRESS, 65536, CERTIFICATE),
+                isArgOrTypeError);
   Expect.throws(() =>
-      RawSecureServerSocket.bind(SERVER_ADDRESS, -1, CERTIFICATE));
-  Expect.throws(() =>
-      RawSecureServerSocket.bind(SERVER_ADDRESS, 0, -1, CERTIFICATE));
+                RawSecureServerSocket.bind(SERVER_ADDRESS, -1, CERTIFICATE),
+                isArgOrTypeError);
+  Expect.throws(() => RawSecureServerSocket.bind(SERVER_ADDRESS, 0,
+                                                 CERTIFICATE, backlog: -1),
+                isArgOrTypeError);
+  Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, 3456,
+                                              sendClientCertificate: true,
+                                              certificateName: 12.3),
+                isArgOrTypeError);
+  Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, null),
+                isArgOrTypeError);
+  Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, -1),
+                isArgOrTypeError);
+  Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, 345656),
+                isArgOrTypeError);
+  Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, 'hest'),
+                isArgOrTypeError);
+  Expect.throws(() => RawSecureSocket.connect(null, 0),
+                isArgOrTypeError);
+  Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, 0,
+                                              certificateName: 77),
+                isArgOrTypeError);
+  Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, 0,
+                                              sendClientCertificate: 'fisk'),
+                isArgOrTypeError);
+  Expect.throws(() => RawSecureSocket.connect(SERVER_ADDRESS, 0,
+                                              onBadCertificate: 'hund'),
+                isArgOrTypeError);
 }
 
 
 main() {
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart',
diff --git a/tests/standalone/io/raw_secure_server_socket_test.dart b/tests/standalone/io/raw_secure_server_socket_test.dart
index fb5f916..dbc0391 100644
--- a/tests/standalone/io/raw_secure_server_socket_test.dart
+++ b/tests/standalone/io/raw_secure_server_socket_test.dart
@@ -86,13 +86,13 @@
         Expect.fail("No client connection expected.");
       })
       .catchError((error) {
-        Expect.isTrue(error is SocketException);
+        Expect.isTrue(error is HandshakeException);
       });
     server.listen((serverEnd) {
       Expect.fail("No server connection expected.");
     },
     onError: (error) {
-      Expect.isTrue(error is SocketException);
+      Expect.isTrue(error is CertificateException);
       clientEndFuture.then((_) {
         if (!cancelOnError) server.close();
         port.close();
@@ -150,10 +150,13 @@
 // server will not happen until the first TLS handshake data has been
 // received from the client. This argument only takes effect when
 // handshakeBeforeSecure is true.
-void testSimpleReadWrite(bool listenSecure,
-                         bool connectSecure,
-                         bool handshakeBeforeSecure,
-                         [bool postponeSecure = false]) {
+void testSimpleReadWrite({bool listenSecure,
+                          bool connectSecure,
+                          bool handshakeBeforeSecure,
+                          bool postponeSecure,
+                          bool dropReads}) {
+  int clientReads = 0;
+  int serverReads = 0;
   if (handshakeBeforeSecure == true &&
       (listenSecure == true || connectSecure == true)) {
     Expect.fail("Invalid arguments to testSimpleReadWrite");
@@ -206,6 +209,14 @@
     subscription = client.listen((event) {
       switch (event) {
         case RawSocketEvent.READ:
+          if (dropReads) {
+            if (serverReads != 10) {
+              ++serverReads;
+              break;
+            } else {
+              serverReads = 0;
+            }
+          }
           Expect.isTrue(bytesWritten == 0);
           Expect.isTrue(client.available() > 0);
           var buffer = client.read();
@@ -257,6 +268,14 @@
       switch (event) {
         case RawSocketEvent.READ:
           Expect.isTrue(socket.available() > 0);
+          if (dropReads) {
+            if (clientReads != 10) {
+              ++clientReads;
+              break;
+            } else {
+              clientReads = 0;
+            }
+          }
           var buffer = socket.read();
           if (buffer != null) {
             dataReceived.setRange(bytesRead, bytesRead + buffer.length, buffer);
@@ -296,6 +315,14 @@
             Expect.isTrue(bytesWritten == 0);
           }
           Expect.isTrue(client.available() > 0);
+          if (dropReads) {
+            if (serverReads != 10) {
+              ++serverReads;
+              break;
+            } else {
+              serverReads = 0;
+            }
+          }
           var buffer = client.read();
           if (buffer != null) {
             if (bytesRead == data.length) {
@@ -354,6 +381,14 @@
     subscription = socket.listen((event) {
       switch (event) {
         case RawSocketEvent.READ:
+          if (dropReads) {
+            if (clientReads != 10) {
+              ++clientReads;
+              break;
+            } else {
+              clientReads = 0;
+            }
+          }
           Expect.isTrue(socket.available() > 0);
           var buffer = socket.read();
           if (buffer != null) {
@@ -435,7 +470,7 @@
 }
 
 main() {
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart',
@@ -449,10 +484,44 @@
   testSimpleConnectFail("not_a_nickname", true);
   testSimpleConnectFail("CN=notARealDistinguishedName", true);
   testServerListenAfterConnect();
-  testSimpleReadWrite(true, true, false);
-  testSimpleReadWrite(true, false, false);
-  testSimpleReadWrite(false, true, false);
-  testSimpleReadWrite(false, false, false);
-  testSimpleReadWrite(false, false, true, true);
-  testSimpleReadWrite(false, false, true, false);
+  testSimpleReadWrite(listenSecure: true,
+                      connectSecure: true,
+                      handshakeBeforeSecure: false,
+                      postponeSecure: false,
+                      dropReads: false);
+  testSimpleReadWrite(listenSecure: true,
+                      connectSecure: false,
+                      handshakeBeforeSecure: false,
+                      postponeSecure: false,
+                      dropReads: false);
+  testSimpleReadWrite(listenSecure: false,
+                      connectSecure: true,
+                      handshakeBeforeSecure: false,
+                      postponeSecure: false,
+                      dropReads: false);
+  testSimpleReadWrite(listenSecure: false,
+                      connectSecure: false,
+                      handshakeBeforeSecure: false,
+                      postponeSecure: false,
+                      dropReads: false);
+  testSimpleReadWrite(listenSecure: false,
+                      connectSecure: false,
+                      handshakeBeforeSecure: true,
+                      postponeSecure: true,
+                      dropReads: false);
+  testSimpleReadWrite(listenSecure: false,
+                      connectSecure: false,
+                      handshakeBeforeSecure: true,
+                      postponeSecure: false,
+                      dropReads: false);
+  testSimpleReadWrite(listenSecure: true,
+                      connectSecure: true,
+                      handshakeBeforeSecure: false,
+                      postponeSecure: false,
+                      dropReads: true);
+  testSimpleReadWrite(listenSecure: false,
+                      connectSecure: false,
+                      handshakeBeforeSecure: true,
+                      postponeSecure: true,
+                      dropReads: true);
 }
diff --git a/tests/standalone/io/raw_secure_socket_pause_test.dart b/tests/standalone/io/raw_secure_socket_pause_test.dart
index a8d01de..a0d678f 100644
--- a/tests/standalone/io/raw_secure_socket_pause_test.dart
+++ b/tests/standalone/io/raw_secure_socket_pause_test.dart
@@ -35,7 +35,7 @@
 
 void InitializeSSL() {
   var testPkcertDatabase =
-      new Path(new Options().script).directoryPath.append('pkcert/');
+      new Path(Platform.script).directoryPath.append('pkcert/');
   SecureSocket.initialize(database: testPkcertDatabase.toNativePath(),
                           password: 'dartdart');
 }
diff --git a/tests/standalone/io/raw_secure_socket_test.dart b/tests/standalone/io/raw_secure_socket_test.dart
index 06d6b83..228bfd3 100644
--- a/tests/standalone/io/raw_secure_socket_test.dart
+++ b/tests/standalone/io/raw_secure_socket_test.dart
@@ -35,7 +35,7 @@
 
 void InitializeSSL() {
   var testPkcertDatabase =
-      new Path(new Options().script).directoryPath.append('pkcert/');
+      new Path(Platform.script).directoryPath.append('pkcert/');
   SecureSocket.initialize(database: testPkcertDatabase.toNativePath(),
                           password: 'dartdart');
 }
diff --git a/tests/standalone/io/raw_socket_test.dart b/tests/standalone/io/raw_socket_test.dart
index 08ed693..1b1b23f 100644
--- a/tests/standalone/io/raw_socket_test.dart
+++ b/tests/standalone/io/raw_socket_test.dart
@@ -123,7 +123,7 @@
   });
 }
 
-void testSimpleReadWrite() {
+void testSimpleReadWrite({bool dropReads}) {
   // This test creates a server and a client connects. The client then
   // writes and the server echos. When the server has finished its
   // echo it half-closes. When the client gets the close event is
@@ -131,6 +131,8 @@
   ReceivePort port = new ReceivePort();
 
   const messageSize = 1000;
+  int serverReadCount = 0;
+  int clientReadCount = 0;
 
   List<int> createTestData() {
     return new List<int>.generate(messageSize, (index) => index & 0xff);
@@ -154,9 +156,17 @@
       client.listen((event) {
         switch (event) {
           case RawSocketEvent.READ:
+            if (dropReads) {
+              if (serverReadCount != 10) {
+                serverReadCount++;
+                break;
+              } else {
+                serverReadCount = 0;
+              }
+            }
             Expect.isTrue(bytesWritten == 0);
             Expect.isTrue(client.available() > 0);
-            var buffer = client.read();
+            var buffer = client.read(200);
             data.setRange(bytesRead, bytesRead + buffer.length, buffer);
             bytesRead += buffer.length;
             if (bytesRead == data.length) {
@@ -192,6 +202,14 @@
         switch (event) {
           case RawSocketEvent.READ:
             Expect.isTrue(socket.available() > 0);
+            if (dropReads) {
+              if (clientReadCount != 10) {
+                clientReadCount++;
+                break;
+              } else {
+                clientReadCount = 0;
+              }
+            }
             var buffer = socket.read();
             data.setRange(bytesRead, bytesRead + buffer.length, buffer);
             bytesRead += buffer.length;
@@ -241,7 +259,7 @@
     // sockets.
     subscription.pause();
     var connectCount = 0;
-    for (int i = 0; i <= socketCount / 2; i++) {
+    for (int i = 0; i < socketCount / 2; i++) {
       RawSocket.connect("127.0.0.1", server.port).then((_) {
         if (++connectCount == socketCount / 2) {
           subscription.resume();
@@ -343,7 +361,8 @@
   testInvalidBind();
   testSimpleConnect();
   testServerListenAfterConnect();
-  testSimpleReadWrite();
+  testSimpleReadWrite(dropReads: false);
+  testSimpleReadWrite(dropReads: true);
   testPauseServerSocket();
   testPauseSocket();
 }
diff --git a/tests/standalone/io/regress_7191_script.dart b/tests/standalone/io/regress_7191_script.dart
index 7bc7a3e..9f7c780 100644
--- a/tests/standalone/io/regress_7191_script.dart
+++ b/tests/standalone/io/regress_7191_script.dart
@@ -11,8 +11,7 @@
   // Start sub-process when receiving data.
   var subscription;
   subscription = stdin.listen((data) {
-    var options = new Options();
-    Process.start(options.executable, [options.script]).then((p) {
+    Process.start(Platform.executable, [Platform.script]).then((p) {
       p.stdout.listen((_) { });
       p.stderr.listen((_) { });
       // When receiving data again, kill sub-process and exit.
diff --git a/tests/standalone/io/regress_7191_test.dart b/tests/standalone/io/regress_7191_test.dart
index 8c56fb3..4e6abf1 100644
--- a/tests/standalone/io/regress_7191_test.dart
+++ b/tests/standalone/io/regress_7191_test.dart
@@ -14,9 +14,8 @@
 
 main() {
   var port = new ReceivePort();
-  var options = new Options();
-  var executable = options.executable;
-  var scriptDir = new Path(options.script).directoryPath;
+  var executable = Platform.executable;
+  var scriptDir = new Path(Platform.script).directoryPath;
   var script = scriptDir.append('regress_7191_script.dart').toNativePath();
   Process.start(executable, [script]).then((process) {
     process.stdin.add([0]);
diff --git a/tests/standalone/io/regress_7679_test.dart b/tests/standalone/io/regress_7679_test.dart
index 30b45d37..9f4c324 100644
--- a/tests/standalone/io/regress_7679_test.dart
+++ b/tests/standalone/io/regress_7679_test.dart
@@ -34,7 +34,7 @@
   });
 }
 """);
-  String executable = new File(new Options().executable).fullPathSync();
+  String executable = new File(Platform.executable).fullPathSync();
   Process.run(executable, ['script.dart'], workingDirectory: temp.path)
       .then((result) {
         temp.deleteSync(recursive: true);
diff --git a/tests/standalone/io/secure_builtin_roots_database_test.dart b/tests/standalone/io/secure_builtin_roots_database_test.dart
index 6b55c71..884123b 100644
--- a/tests/standalone/io/secure_builtin_roots_database_test.dart
+++ b/tests/standalone/io/secure_builtin_roots_database_test.dart
@@ -23,7 +23,7 @@
   // If the built-in root certificates aren't loaded, the connection
   // should signal an error.  Even when an external database is loaded,
   // they should not be loaded.
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart',
diff --git a/tests/standalone/io/secure_client_raw_server_test.dart b/tests/standalone/io/secure_client_raw_server_test.dart
index 1fce350..4f6fa0c 100644
--- a/tests/standalone/io/secure_client_raw_server_test.dart
+++ b/tests/standalone/io/secure_client_raw_server_test.dart
@@ -77,7 +77,7 @@
 }
 
 void main() {
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart');
diff --git a/tests/standalone/io/secure_client_server_test.dart b/tests/standalone/io/secure_client_server_test.dart
index 11cf433..9806444b 100644
--- a/tests/standalone/io/secure_client_server_test.dart
+++ b/tests/standalone/io/secure_client_server_test.dart
@@ -42,7 +42,7 @@
 }
 
 void main() {
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart');
diff --git a/tests/standalone/io/secure_multiple_client_server_test.dart b/tests/standalone/io/secure_multiple_client_server_test.dart
index e0e91e4..b5af21a 100644
--- a/tests/standalone/io/secure_multiple_client_server_test.dart
+++ b/tests/standalone/io/secure_multiple_client_server_test.dart
@@ -45,7 +45,7 @@
 }
 
 void main() {
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart');
diff --git a/tests/standalone/io/secure_no_builtin_roots_database_test.dart b/tests/standalone/io/secure_no_builtin_roots_database_test.dart
index b5a06af..1affafb 100644
--- a/tests/standalone/io/secure_no_builtin_roots_database_test.dart
+++ b/tests/standalone/io/secure_no_builtin_roots_database_test.dart
@@ -14,7 +14,7 @@
       .then((request) => request.close())
       .then((response) => Expect.fail("Unexpected successful connection"))
       .catchError((error) {
-        Expect.isTrue(error is SocketException);
+        Expect.isTrue(error is HandshakeException);
         keepAlive.close();
         client.close();
       });
@@ -24,7 +24,7 @@
   // If the built-in root certificates aren't loaded, the connection
   // should signal an error.  Even when an external database is loaded,
   // they should not be loaded.
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart',
diff --git a/tests/standalone/io/secure_no_builtin_roots_test.dart b/tests/standalone/io/secure_no_builtin_roots_test.dart
index 9bc5ef6..4bcdac8 100644
--- a/tests/standalone/io/secure_no_builtin_roots_test.dart
+++ b/tests/standalone/io/secure_no_builtin_roots_test.dart
@@ -14,7 +14,7 @@
       .then((request) => request.close())
       .then((response) => Expect.fail("Unexpected successful connection"))
       .catchError((error) {
-        Expect.isTrue(error is SocketException);
+        Expect.isTrue(error is HandshakeException);
         keepAlive.close();
         client.close();
       });
diff --git a/tests/standalone/io/secure_server_client_certificate_test.dart b/tests/standalone/io/secure_server_client_certificate_test.dart
index 35475e2..4aafbc6 100644
--- a/tests/standalone/io/secure_server_client_certificate_test.dart
+++ b/tests/standalone/io/secure_server_client_certificate_test.dart
@@ -110,7 +110,7 @@
 }
 
 void main() {
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart',
diff --git a/tests/standalone/io/secure_server_closing_test.dart b/tests/standalone/io/secure_server_closing_test.dart
index 0d27cb2..67b70fd 100644
--- a/tests/standalone/io/secure_server_closing_test.dart
+++ b/tests/standalone/io/secure_server_closing_test.dart
@@ -151,7 +151,7 @@
 
 
 main() {
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart',
diff --git a/tests/standalone/io/secure_server_socket_test.dart b/tests/standalone/io/secure_server_socket_test.dart
index 9563fc9..2d36fed 100644
--- a/tests/standalone/io/secure_server_socket_test.dart
+++ b/tests/standalone/io/secure_server_socket_test.dart
@@ -83,13 +83,13 @@
         Expect.fail("No client connection expected.");
       })
       .catchError((error) {
-        Expect.isTrue(error is SocketException);
+        Expect.isTrue(error is HandshakeException);
       });
     server.listen((serverEnd) {
       Expect.fail("No server connection expected.");
     },
     onError: (error) {
-      Expect.isTrue(error is SocketException);
+      Expect.isTrue(error is CertificateException);
       clientEndFuture.then((_) {
         if (!cancelOnError) server.close();
         port.close();
@@ -186,7 +186,7 @@
 }
 
 main() {
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart',
diff --git a/tests/standalone/io/secure_session_resume_test.dart b/tests/standalone/io/secure_session_resume_test.dart
index 17873e8..e287e37 100644
--- a/tests/standalone/io/secure_session_resume_test.dart
+++ b/tests/standalone/io/secure_session_resume_test.dart
@@ -54,7 +54,7 @@
 }
 
 void main() {
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart');
diff --git a/tests/standalone/io/secure_socket_bad_certificate_test.dart b/tests/standalone/io/secure_socket_bad_certificate_test.dart
index 85b1cd3..dbd13d1e 100644
--- a/tests/standalone/io/secure_socket_bad_certificate_test.dart
+++ b/tests/standalone/io/secure_socket_bad_certificate_test.dart
@@ -31,12 +31,9 @@
 }
 
 Future testCertificateCallback({String host, bool acceptCertificate}) {
-  try {
-    var x = 7;
-    SecureSocket.connect(host, 443, onBadCertificate: x)
-        .catchError((e) {}, test: (e) => e is ArgumentError);
-  } on TypeError catch (e) {
-  }
+  var x = 7;
+  Expect.throws(() => SecureSocket.connect(host, 443, onBadCertificate: x),
+                (e) => e is ArgumentError || e is TypeError);
 
   bool badCertificateCallback(X509Certificate certificate) {
     Expect.isTrue(certificate.subject.contains("O=Google Inc"));
diff --git a/tests/standalone/io/secure_socket_test.dart b/tests/standalone/io/secure_socket_test.dart
index 84a9fb8..d9ff854 100644
--- a/tests/standalone/io/secure_socket_test.dart
+++ b/tests/standalone/io/secure_socket_test.dart
@@ -34,7 +34,7 @@
 
 void InitializeSSL() {
   var testPkcertDatabase =
-      new Path(new Options().script).directoryPath.append('pkcert/');
+      new Path(Platform.script).directoryPath.append('pkcert/');
   SecureSocket.initialize(database: testPkcertDatabase.toNativePath(),
                           password: 'dartdart');
 }
diff --git a/tests/standalone/io/skipping_dart2js_compilations_helper.dart b/tests/standalone/io/skipping_dart2js_compilations_helper.dart
index 1728e3a..88a26c2 100644
--- a/tests/standalone/io/skipping_dart2js_compilations_helper.dart
+++ b/tests/standalone/io/skipping_dart2js_compilations_helper.dart
@@ -5,7 +5,7 @@
 import 'dart:io';
 
 main() {
-  var outputFile = new Options().arguments[0];
+  var outputFile = Platform.arguments[0];
   var file = new File(outputFile);
   file.createSync();
 }
diff --git a/tests/standalone/io/skipping_dart2js_compilations_test.dart b/tests/standalone/io/skipping_dart2js_compilations_test.dart
index d018541..dfb71a5 100644
--- a/tests/standalone/io/skipping_dart2js_compilations_test.dart
+++ b/tests/standalone/io/skipping_dart2js_compilations_test.dart
@@ -146,10 +146,10 @@
 
 runner.TestCase makeTestCase(String testName, FileUtils fileUtils) {
   var config = new options.TestOptionsParser().parse(['--timeout', '2'])[0];
-  var scriptDirPath = new Path(new Options().script).directoryPath;
+  var scriptDirPath = new Path(Platform.script).directoryPath;
   var createFileScript = scriptDirPath.
       append('skipping_dart2js_compilations_helper.dart').toNativePath();
-  var executable = new Options().executable;
+  var executable = Platform.executable;
   var arguments = [createFileScript, fileUtils.scriptOutputPath.toNativePath()];
   var bootstrapDeps = [
       Uri.parse("file://${fileUtils.testSnapshotFilePath}")];
diff --git a/tests/standalone/io/socket_upgrade_to_secure_test.dart b/tests/standalone/io/socket_upgrade_to_secure_test.dart
index cc66ce8..8564c98 100644
--- a/tests/standalone/io/socket_upgrade_to_secure_test.dart
+++ b/tests/standalone/io/socket_upgrade_to_secure_test.dart
@@ -211,7 +211,7 @@
 }
 
 main() {
-  Path scriptDir = new Path(new Options().script).directoryPath;
+  Path scriptDir = new Path(Platform.script).directoryPath;
   Path certificateDatabase = scriptDir.append('pkcert');
   SecureSocket.initialize(database: certificateDatabase.toNativePath(),
                           password: 'dartdart',
diff --git a/tests/standalone/io/string_decoder_test.dart b/tests/standalone/io/string_decoder_test.dart
index df808ae..6e96000 100644
--- a/tests/standalone/io/string_decoder_test.dart
+++ b/tests/standalone/io/string_decoder_test.dart
@@ -6,7 +6,7 @@
 import "dart:async";
 import "dart:io";
 
-void test() {
+void testTransform() {
   // Code point U+10FFFF is the largest code point supported by Dart.
   var controller = new StreamController(sync: true);
   controller.add([0xf0, 0x90, 0x80, 0x80]);  // U+10000
@@ -40,6 +40,33 @@
       });
 }
 
+void testDecode() {
+  // Code point U+10FFFF is the largest code point supported by Dart.
+  var controller = new StreamController(sync: true);
+  controller.add([0xf0, 0x90, 0x80, 0x80]);  // U+10000
+  controller.add([0xf4, 0x8f, 0xbf, 0xbf]);  // U+10FFFF
+  controller.add([0xf4, 0x90, 0x80, 0x80]);  // U+110000
+  controller.add([0xfa, 0x80, 0x80, 0x80, 0x80]);  //  U+2000000
+  controller.add([0xfd, 0x80, 0x80, 0x80, 0x80, 0x80]);  // U+40000000
+  controller.close();
+
+  StringDecoder.decode(controller.stream,
+                       Encoding.UTF_8,
+                       '?'.codeUnitAt(0)).then((decoded) {
+    Expect.equals(8, decoded.length);
+
+    var replacementChar = '?'.codeUnitAt(0);
+    Expect.equals(0xd800, decoded.codeUnitAt(0));
+    Expect.equals(0xdc00, decoded.codeUnitAt(1));
+    Expect.equals(0xdbff, decoded.codeUnitAt(2));
+    Expect.equals(0xdfff, decoded.codeUnitAt(3));
+    Expect.equals(replacementChar, decoded.codeUnitAt(4));
+    Expect.equals(replacementChar, decoded.codeUnitAt(5));
+    Expect.equals(replacementChar, decoded.codeUnitAt(6));
+    Expect.equals(replacementChar, decoded.codeUnitAt(7));
+  });
+}
+
 void testInvalid() {
   void invalid(var bytes, var outputLength) {
     var controller = new StreamController(sync: true);
@@ -61,6 +88,7 @@
 }
 
 void main() {
-  test();
+  testTransform();
+  testDecode();
   testInvalid();
 }
diff --git a/tests/standalone/io/test_extension_fail_test.dart b/tests/standalone/io/test_extension_fail_test.dart
index 96d0a3a..aa10592 100644
--- a/tests/standalone/io/test_extension_fail_test.dart
+++ b/tests/standalone/io/test_extension_fail_test.dart
@@ -37,10 +37,8 @@
 }
 
 void main() {
-  Options options = new Options();
-
-  Path scriptDirectory = new Path(options.script).directoryPath;
-  Path buildDirectory = new Path(options.executable).directoryPath;
+  Path scriptDirectory = new Path(Platform.script).directoryPath;
+  Path buildDirectory = new Path(Platform.executable).directoryPath;
   Directory tempDirectory = new Directory('').createTempSync();
   Path testDirectory = new Path(tempDirectory.path);
 
@@ -56,7 +54,7 @@
     return copyFileToDirectory(testExtensionTesterFile, testDirectory);
   }).then((_) {
     Path script = testDirectory.append('test_extension_fail_tester.dart');
-    return Process.run(options.executable, [script.toNativePath()]);
+    return Process.run(Platform.executable, [script.toNativePath()]);
   }).then((ProcessResult result) {
     print("ERR: ${result.stderr}\n\n");
     print("OUT: ${result.stdout}\n\n");
diff --git a/tests/standalone/io/test_extension_test.dart b/tests/standalone/io/test_extension_test.dart
index 9961daf..f4b73c8 100644
--- a/tests/standalone/io/test_extension_test.dart
+++ b/tests/standalone/io/test_extension_test.dart
@@ -37,10 +37,8 @@
 }
 
 void main() {
-  Options options = new Options();
-
-  Path scriptDirectory = new Path(options.script).directoryPath;
-  Path buildDirectory = new Path(options.executable).directoryPath;
+  Path scriptDirectory = new Path(Platform.script).directoryPath;
+  Path buildDirectory = new Path(Platform.executable).directoryPath;
   Directory tempDirectory = new Directory('').createTempSync();
   Path testDirectory = new Path(tempDirectory.path);
 
@@ -56,7 +54,7 @@
     return copyFileToDirectory(testExtensionTesterFile, testDirectory);
   }).then((_) {
     Path script = testDirectory.append('test_extension_tester.dart');
-    return Process.run(options.executable, [script.toNativePath()]);
+    return Process.run(Platform.executable, [script.toNativePath()]);
   })..then((ProcessResult result) {
     Expect.equals(0, result.exitCode);
     tempDirectory.deleteSync(recursive: true);
diff --git a/tests/standalone/io/test_runner_exit_code_script.dart b/tests/standalone/io/test_runner_exit_code_script.dart
index 1cfe603..02ca770 100644
--- a/tests/standalone/io/test_runner_exit_code_script.dart
+++ b/tests/standalone/io/test_runner_exit_code_script.dart
@@ -10,7 +10,7 @@
 import "../../../tools/testing/dart/test_options.dart";
 
 main() {
-  var progressType = new Options().arguments[0];
+  var progressType = Platform.arguments[0];
   // Build a progress indicator.
   var startTime = new DateTime.now();
   var progress =
diff --git a/tests/standalone/io/test_runner_test.dart b/tests/standalone/io/test_runner_test.dart
index f4a975d..fa276c2 100644
--- a/tests/standalone/io/test_runner_test.dart
+++ b/tests/standalone/io/test_runner_test.dart
@@ -71,8 +71,8 @@
   }
 
   TestCase _makeNormalTestCase(name, expectations) {
-    var command = new Command(new Options().executable,
-                              [new Options().script, name]);
+    var command = new Command(Platform.executable,
+                              [Platform.script, name]);
     return _makeTestCase(name, DEFAULT_TIMEOUT, command, expectations);
   }
 
@@ -109,7 +109,7 @@
   // Run the test_runner_test if there are no command-line options.
   // Otherwise, run one of the component tests that always pass,
   // fail, or timeout.
-  var arguments = new Options().arguments;
+  var arguments = Platform.arguments;
   if (arguments.isEmpty) {
     testProcessQueue();
   } else {
diff --git a/tests/standalone/io/web_socket_test.dart b/tests/standalone/io/web_socket_test.dart
index cd72efa..96db483 100644
--- a/tests/standalone/io/web_socket_test.dart
+++ b/tests/standalone/io/web_socket_test.dart
@@ -405,7 +405,7 @@
 
 void initializeSSL() {
   var testPkcertDatabase =
-      new Path(new Options().script).directoryPath.append("pkcert/");
+      new Path(Platform.script).directoryPath.append("pkcert/");
   SecureSocket.initialize(database: testPkcertDatabase.toNativePath(),
                           password: "dartdart");
 }
diff --git a/tests/standalone/io/windows_environment_test.dart b/tests/standalone/io/windows_environment_test.dart
index 6508da8..017132f 100644
--- a/tests/standalone/io/windows_environment_test.dart
+++ b/tests/standalone/io/windows_environment_test.dart
@@ -16,9 +16,8 @@
 set SCRIPTDIR=%~dp0
 %1 %2
       """);
-  var options = new Options();
-  var dart = options.executable;
-  var scriptDir = new Path(options.script).directoryPath;
+  var dart = Platform.executable;
+  var scriptDir = new Path(Platform.script).directoryPath;
   var script = scriptDir.append('windows_environment_script.dart');
   Process.run('cmd',
               ['/c', funkyFile.path, dart, script.toNativePath()]).then((p) {
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index e08da8e..c855cff 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -15,6 +15,7 @@
 # Fails because checked-in dart executable is not up to date.
 # Skip this because it is leaving temp directories behind when it fails.
 io/skipping_dart2js_compilations_test: Skip
+io/web_socket_test: Pass, Crash # Issue 11502
 
 [ $runtime == vm ]
 package/package_isolate_test: Fail # http://dartbug.com/7520.
@@ -81,15 +82,24 @@
 
 
 [ $compiler == dartanalyzer ]
-io/file_constructor_test: fail
-io/http_cookie_date_test: fail
-io/http_headers_test: fail
-io/http_parser_test: fail
-io/process_exit_negative_test: fail
-io/url_encoding_test: fail
-io/web_socket_protocol_processor_test: fail
 53bit_overflow_literal_test/01: fail, ok
 
+# test issue https://code.google.com/p/dart/issues/detail?id=11518
+io/file_constructor_test: fail
+
+# The dart:io library is created at build time from separate files, and
+# there is no language-spec compatible way to run unit tests on the private
+# members and methods of dart:io.
+# Dart analyzer spots the misuse of 'part' directives in these unit tests.
+io/http_headers_test: Skip
+io/http_cookie_date_test: Skip
+io/url_encoding_test: Skip
+io/http_parser_test: Skip
+io/web_socket_protocol_processor_test: Skip
+
+# This is runtime test.
+io/process_exit_negative_test: Skip
+
 # Fails because checked-in dart executable is not up to date.
 io/test_runner_test: fail
 io/skipping_dart2js_compilations_test: fail
@@ -153,22 +163,15 @@
 [ $compiler == dart2js && $checked ]
 io/http_read_test: Skip # Timeout TODO(ngeoffray): investigate
 io/list_input_stream_test: Skip # Timeout TODO(ngeoffray): investigate
+io/http_parser_test: Fail # dartbug.com/11273
 
 [ $compiler == dart2dart ]
 # Skip until we stabilize language tests.
 *: Skip
 
 [ $arch == arm || $arch == simarm ]
-coverage_test: Crash # Issue: 11207
-debugger/basic_debugger_test: Crash # Issue: 11207
-debugger/closure_debugger_test: Crash # Issue: 11207
-http_launch_test: Fail, Crash # Issue: 11207
-left_shift_bit_and_op_test: Fail # Issue: 11207
-package/package_isolate_test: Pass, Crash # Issue: 11207
-out_of_memory_test: Pass, Crash # Issue: 11207 (Pass on Mac)
-typed_data_test: Timeout, Crash # Issue: 11207
-typed_data_isolate_test: Pass, Crash # Issue: 11207
-io/*: Skip # Skip IO tests for now as they are still quite flaky.
+*: Skip # Many of these tests are still flaky on arm, so skipping until we
+        # actually start working on implementing the needed features.
 
 [ $arch == mips ]
 *: Skip
diff --git a/tests/standalone/typed_data_isolate_test.dart b/tests/standalone/typed_data_isolate_test.dart
index 086a20f..852cc1e 100644
--- a/tests/standalone/typed_data_isolate_test.dart
+++ b/tests/standalone/typed_data_isolate_test.dart
@@ -22,7 +22,7 @@
 }
 
 main() {
- new File(new Options().script).readAsBytes().then((List<int> data) {
+ new File(Platform.script).readAsBytes().then((List<int> data) {
    spawnFunction(second).call(data).then((reply) {
      print('got reply');
      port.close();
diff --git a/tools/VERSION b/tools/VERSION
index ed3d747..9ed370f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
-MINOR 5
-BUILD 20
-PATCH 4
+MINOR 6
+BUILD 0
+PATCH 0
diff --git a/tools/bots/compiler.py b/tools/bots/compiler.py
index 9dab287..82eafe2 100644
--- a/tools/bots/compiler.py
+++ b/tools/bots/compiler.py
@@ -164,6 +164,8 @@
 
     if UseBrowserController(runtime, system):
       cmd.append('--use_browser_controller')
+    if runtime == 'safari':
+      cmd.append('--clear_safari_cache')
 
     global IsFirstTestStepCall
     if IsFirstTestStepCall:
diff --git a/tools/bots/editor.py b/tools/bots/editor.py
index 80d85d4..6879b93 100755
--- a/tools/bots/editor.py
+++ b/tools/bots/editor.py
@@ -4,12 +4,22 @@
 # BSD-style license that can be found in the LICENSE file.
 
 import os
+import re
 import shutil
 import sys
 import tempfile
 
 import bot
 
+SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
+sys.path.append(os.path.join(SCRIPT_DIR, '..'))
+import utils
+
+
+GSUTIL = utils.GetBuildbotGSUtilPath()
+GCS_DARTIUM_BUCKET = "gs://dartium-archive/continuous"
+GCS_EDITOR_BUCKET = "gs://continuous-editor-archive"
+
 class TempDir(object):
   def __enter__(self):
     self._temp_dir = tempfile.mkdtemp('eclipse-workspace')
@@ -18,31 +28,95 @@
   def __exit__(self, *_):
     shutil.rmtree(self._temp_dir, ignore_errors = True)
 
-def GetEditorExecutable(mode, arch):
+def GetBuildDirectory(mode, arch):
   configuration_dir = mode + arch.upper()
-  linux_path = os.path.join('out', configuration_dir, 'editor')
-  win_path = os.path.join('build', configuration_dir, 'editor')
-  mac_path = os.path.join('xcodebuild', configuration_dir, 'editor')
+  build_directory_dict = {
+    'linux2' : os.path.join('out', configuration_dir),
+    'darwin' : os.path.join('xcodebuild', configuration_dir),
+    'win32' : os.path.join('build', configuration_dir),
+  }
+  if sys.platform == 'darwin':
+    # TODO(kustermann,ricow): Maybe we're able to get rid of this in the future.
+    # We use ninja on bots which use out/ (i.e. what linux2 does) instead of
+    # xcodebuild/
+    if (os.path.exists(build_directory_dict['linux2']) and
+        os.path.isdir(build_directory_dict['linux2'])):
+      return build_directory_dict['linux2']
+  return build_directory_dict[sys.platform]
 
+def GetEditorDirectory(mode, arch):
+  return os.path.join(GetBuildDirectory(mode, arch), 'editor')
+
+def GetDartSdkDirectory(mode, arch):
+  return os.path.join(GetBuildDirectory(mode, arch), 'dart-sdk')
+
+def GetEditorExecutable(mode, arch):
+  editor_dir = GetEditorDirectory(mode, arch)
   if sys.platform == 'darwin':
     executable = os.path.join('DartEditor.app', 'Contents', 'MacOS',
                               'DartEditor')
-    # TODO(kustermann,ricow): Maybe we're able to get rid of this in the future.
-    # We use ninja on bots which use out/ instead of xcodebuild/
-    if os.path.exists(linux_path) and os.path.isdir(linux_path):
-      return os.path.join(linux_path, executable)
-    else:
-      return os.path.join(mac_path, executable)
   elif sys.platform == 'win32':
-    return os.path.join(win_path, 'DartEditor.exe')
+    executable = 'DartEditor.exe'
   elif sys.platform == 'linux2':
-    return os.path.join(linux_path, 'DartEditor')
+    executable = 'DartEditor'
   else:
     raise Exception('Unknown platform %s' % sys.platform)
+  return os.path.join(editor_dir, executable)
 
+def RunProcess(args):
+  print 'Running: %s' % (' '.join(args))
+  sys.stdout.flush()
+  bot.RunProcess(args)
+
+def DownloadDartium(temp_dir, zip_file):
+  """Returns the filename of the unpacked archive"""
+  local_path = os.path.join(temp_dir, zip_file)
+  uri = "%s/%s" % (GCS_DARTIUM_BUCKET, zip_file)
+  RunProcess([GSUTIL, 'cp', uri, local_path])
+  RunProcess(['unzip', local_path, '-d', temp_dir])
+  for filename in os.listdir(temp_dir):
+    match = re.search('^dartium-.*-inc-([0-9]+)\.0$', filename)
+    if match:
+      return os.path.join(temp_dir, match.group(0))
+  raise Exception("Couldn't find dartium archive")
+
+def UploadInstaller(dart_editor_dmg, directory):
+  directory = directory % {'revision' : utils.GetSVNRevision()}
+  uri = '%s/%s' % (GCS_EDITOR_BUCKET, directory)
+  RunProcess([GSUTIL, 'cp', dart_editor_dmg, uri])
+
+def CreateAndUploadMacInstaller(arch):
+  dart_icns = os.path.join(
+    'editor', 'tools', 'plugins', 'com.google.dart.tools.deploy',
+    'icons', 'dart.icns')
+  mac_build_bundle_py = os.path.join('tools', 'mac_build_editor_bundle.sh')
+  mac_build_dmg_py = os.path.join('tools', 'mac_build_editor_dmg.sh')
+  editor_dir = GetEditorDirectory('Release', arch)
+  dart_sdk = GetDartSdkDirectory('Release', arch)
+  with TempDir() as temp_dir:
+    # Get dartium
+    dartium_directory = DownloadDartium(temp_dir, 'dartium-mac.zip')
+    dartium_bundle_dir = os.path.join(dartium_directory,
+                                      'Chromium.app')
+
+    # Build the editor bundle
+    darteditor_bundle_dir = os.path.join(temp_dir, 'DartEditor.app')
+    args = [mac_build_bundle_py, darteditor_bundle_dir, editor_dir,
+           dart_sdk, dartium_bundle_dir, dart_icns]
+    RunProcess(args)
+
+    # Build the dmg installer from the editor bundle
+    dart_editor_dmg = os.path.join(temp_dir, 'DartEditor.dmg')
+    args = [mac_build_dmg_py, dart_editor_dmg, darteditor_bundle_dir,
+            dart_icns, 'Dart Editor']
+    RunProcess(args)
+
+    # Upload the dmg installer
+    UploadInstaller(dart_editor_dmg, 'dart-editor-mac-%(revision)s.dmg')
 
 def main():
   build_py = os.path.join('tools', 'build.py')
+
   architectures = ['ia32', 'x64']
   test_architectures = ['x64']
   if sys.platform == 'win32':
@@ -52,19 +126,24 @@
   for arch in architectures:
     with bot.BuildStep('Build Editor %s' % arch):
       args = [sys.executable, build_py,
-              '-mrelease', '--arch=%s' % arch, 'editor']
-      print 'Running: %s' % (' '.join(args))
-      sys.stdout.flush()
-      bot.RunProcess(args)
+              '-mrelease', '--arch=%s' % arch, 'editor', 'create_sdk']
+      RunProcess(args)
 
   for arch in test_architectures:
     editor_executable = GetEditorExecutable('Release', arch)
     with bot.BuildStep('Test Editor %s' % arch):
       with TempDir() as temp_dir:
         args = [editor_executable, '--test', '--auto-exit', '-data', temp_dir]
-        print 'Running: %s' % (' '.join(args))
-        sys.stdout.flush()
-        bot.RunProcess(args)
+        RunProcess(args)
+
+  # TODO: Permissions need to be clarified
+  for arch in test_architectures:
+    with bot.BuildStep('Build Installer %s' % arch):
+      if sys.platform == 'darwin':
+        CreateAndUploadMacInstaller(arch)
+      else:
+        print ("We currently don't build installers for sys.platform=%s"
+                % sys.platform)
   return 0
 
 if __name__ == '__main__':
diff --git a/tools/build.py b/tools/build.py
index c666fbab..8b6fbf3 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -344,112 +344,113 @@
   # Determine which targets to build. By default we build the "all" target.
   if len(args) == 0:
     if HOST_OS == 'macos':
-      target = 'All'
+      targets = ['All']
     else:
-      target = 'all'
+      targets = ['all']
   else:
-    target = args[0]
+    targets = args
 
   filter_xcodebuild_output = False
   # Remember path
   old_path = os.environ['PATH']
-  # Build the targets for each requested configuration.
-  for target_os in options.os:
-    for mode in options.mode:
-      for arch in options.arch:
-        os.environ['DART_BUILD_MODE'] = mode
-        build_config = utils.GetBuildConf(mode, arch)
-        if HOST_OS == 'macos':
-          filter_xcodebuild_output = True
-          project_file = 'dart.xcodeproj'
-          if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
-            project_file = 'dart-%s.xcodeproj' % CurrentDirectoryBaseName()
-          args = ['xcodebuild',
-                  '-project',
-                  project_file,
-                  '-target',
-                  target,
-                  '-configuration',
-                  build_config,
-                  'SYMROOT=%s' % os.path.abspath('xcodebuild')
-                  ]
-        elif HOST_OS == 'win32':
-          project_file = 'dart.sln'
-          if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
-            project_file = 'dart-%s.sln' % CurrentDirectoryBaseName()
-          if target == 'all':
-            args = [options.devenv + os.sep + options.executable,
-                    '/build',
-                    build_config,
-                    project_file
-                   ]
-          else:
-            args = [options.devenv + os.sep + options.executable,
-                    '/build',
-                    build_config,
-                    '/project',
+  # Build all targets for each requested configuration.
+  for target in targets:
+    for target_os in options.os:
+      for mode in options.mode:
+        for arch in options.arch:
+          os.environ['DART_BUILD_MODE'] = mode
+          build_config = utils.GetBuildConf(mode, arch)
+          if HOST_OS == 'macos':
+            filter_xcodebuild_output = True
+            project_file = 'dart.xcodeproj'
+            if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
+              project_file = 'dart-%s.xcodeproj' % CurrentDirectoryBaseName()
+            args = ['xcodebuild',
+                    '-project',
+                    project_file,
+                    '-target',
                     target,
-                    project_file
-                   ]
-        else:
-          make = 'make'
-          if HOST_OS == 'freebsd':
-            make = 'gmake'
-            # work around lack of flock
-            os.environ['LINK'] = '$(CXX)'
-          args = [make,
-                  '-j',
-                  options.j,
-                  'BUILDTYPE=' + build_config,
-                  ]
-          if target_os != HOST_OS:
-            args += ['builddir_name=' + utils.GetBuildDir(HOST_OS, target_os)]
-          if options.verbose:
-            args += ['V=1']
-
-          args += [target]
-
-        if target_os != HOST_OS:
-          SetCrossCompilationEnvironment(
-              HOST_OS, target_os, arch, old_path)
-
-        RunhooksIfNeeded(HOST_OS, mode, arch, target_os)
-
-        toolchainprefix = None
-        if target_os == 'android':
-          toolchainprefix = ('%s/i686-linux-android'
-                              % os.environ['ANDROID_TOOLCHAIN'])
-        toolsOverride = SetTools(arch, toolchainprefix)
-        if toolsOverride:
-          printToolOverrides = target_os != 'android'
-          for k, v in toolsOverride.iteritems():
-            args.append(  k + "=" + v)
-            if printToolOverrides:
-              print k + " = " + v
-          if not os.path.isfile(toolsOverride['CC.target']):
-            if arch == 'arm':
-              print arm_cc_error
+                    '-configuration',
+                    build_config,
+                    'SYMROOT=%s' % os.path.abspath('xcodebuild')
+                    ]
+          elif HOST_OS == 'win32':
+            project_file = 'dart.sln'
+            if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
+              project_file = 'dart-%s.sln' % CurrentDirectoryBaseName()
+            if target == 'all':
+              args = [options.devenv + os.sep + options.executable,
+                      '/build',
+                      build_config,
+                      project_file
+                     ]
             else:
-              print "Couldn't find compiler: %s" % toolsOverride['CC.target']
+              args = [options.devenv + os.sep + options.executable,
+                      '/build',
+                      build_config,
+                      '/project',
+                      target,
+                      project_file
+                     ]
+          else:
+            make = 'make'
+            if HOST_OS == 'freebsd':
+              make = 'gmake'
+              # work around lack of flock
+              os.environ['LINK'] = '$(CXX)'
+            args = [make,
+                    '-j',
+                    options.j,
+                    'BUILDTYPE=' + build_config,
+                    ]
+            if target_os != HOST_OS:
+              args += ['builddir_name=' + utils.GetBuildDir(HOST_OS, target_os)]
+            if options.verbose:
+              args += ['V=1']
+
+            args += [target]
+
+          if target_os != HOST_OS:
+            SetCrossCompilationEnvironment(
+                HOST_OS, target_os, arch, old_path)
+
+          RunhooksIfNeeded(HOST_OS, mode, arch, target_os)
+
+          toolchainprefix = None
+          if target_os == 'android':
+            toolchainprefix = ('%s/i686-linux-android'
+                                % os.environ['ANDROID_TOOLCHAIN'])
+          toolsOverride = SetTools(arch, toolchainprefix)
+          if toolsOverride:
+            printToolOverrides = target_os != 'android'
+            for k, v in toolsOverride.iteritems():
+              args.append(  k + "=" + v)
+              if printToolOverrides:
+                print k + " = " + v
+            if not os.path.isfile(toolsOverride['CC.target']):
+              if arch == 'arm':
+                print arm_cc_error
+              else:
+                print "Couldn't find compiler: %s" % toolsOverride['CC.target']
+              return 1
+
+
+          print ' '.join(args)
+          process = None
+          if filter_xcodebuild_output:
+            process = subprocess.Popen(args,
+                                       stdin=None,
+                                       bufsize=1, # Line buffered.
+                                       stdout=subprocess.PIPE,
+                                       stderr=subprocess.STDOUT)
+            FilterEmptyXcodebuildSections(process)
+          else:
+            process = subprocess.Popen(args, stdin=None)
+          process.wait()
+          if process.returncode != 0:
+            print "BUILD FAILED"
             return 1
 
-
-        print ' '.join(args)
-        process = None
-        if filter_xcodebuild_output:
-          process = subprocess.Popen(args,
-                                     stdin=None,
-                                     bufsize=1, # Line buffered.
-                                     stdout=subprocess.PIPE,
-                                     stderr=subprocess.STDOUT)
-          FilterEmptyXcodebuildSections(process)
-        else:
-          process = subprocess.Popen(args, stdin=None)
-        process.wait()
-        if process.returncode != 0:
-          print "BUILD FAILED"
-          return 1
-
   return 0
 
 
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index 3ba329e..5c8279d 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -257,7 +257,7 @@
           "   *     var ctx = canvas.context2D",
           "   *     ..fillStyle = \"rgb(200,0,0)\"",
           "   *     ..fillRect(10, 10, 55, 50);",
-          "   *     var dataUrl = canvas.toDataURL(\"image/jpeg\", 0.95);",
+          "   *     var dataUrl = canvas.toDataUrl(\"image/jpeg\", 0.95);",
           "   *     // The Data Uri would look similar to",
           "   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA",
           "   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO",
@@ -363,7 +363,7 @@
         " *",
         " * To receive data on the WebSocket, register a listener for message events.",
         " *",
-        " *     webSocket.on.message.add((MessageEvent e) {",
+        " *     webSocket.onMessage.listen((MessageEvent e) {",
         " *       receivedData(e.data);",
         " *     });",
         " *",
diff --git a/tools/dom/dom.json b/tools/dom/dom.json
index 67bf2043..0fba769 100644
--- a/tools/dom/dom.json
+++ b/tools/dom/dom.json
@@ -2153,7 +2153,8 @@
       "DRAW_BUFFER8_EXT": {},
       "DRAW_BUFFER9_EXT": {},
       "MAX_COLOR_ATTACHMENTS_EXT": {},
-      "MAX_DRAW_BUFFERS_EXT": {}
+      "MAX_DRAW_BUFFERS_EXT": {},
+      "drawBuffersEXT": {}
     },
     "support_level": "stable"
   },
diff --git a/tools/dom/scripts/dartgenerator.py b/tools/dom/scripts/dartgenerator.py
index 4f6de3a..8635eff 100755
--- a/tools/dom/scripts/dartgenerator.py
+++ b/tools/dom/scripts/dartgenerator.py
@@ -85,7 +85,10 @@
           if (type_name is not None and
               self._IsCompoundType(database, type_name)):
             continue
-          _logger.warn('removing %s in %s which has unidentified type %s' %
+          # Ignore constructor warnings.
+          if not (interface.id in ['DOMWindow', 'WorkerContext'] and
+              type_name.endswith('Constructor')):
+            _logger.warn('removing %s in %s which has unidentified type %s' %
                        (node_name, interface.id, type_name))
           return False
         return True
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
index 34d151a..4d1b866 100644
--- a/tools/dom/scripts/dartmetadata.py
+++ b/tools/dom/scripts/dartmetadata.py
@@ -198,7 +198,7 @@
       "@Returns('int|String|Null')",
     ],
 
-    'MessageEvent.ports': ["@Creates('=List')"],
+    'MessageEvent.ports': ["@Creates('JSExtendableArray')"],
 
     'MessageEvent.data': [
       "@annotation_Creates_SerializedScriptValue",
@@ -271,8 +271,10 @@
     ],
 
     'WebGLRenderingContext.getUniform': [
-      "@Creates('Null|num|String|bool|=List|Float32List|Int32List|Uint32List')",
-      "@Returns('Null|num|String|bool|=List|Float32List|Int32List|Uint32List')",
+      "@Creates('Null|num|String|bool|JSExtendableArray|Float32List|Int32List"
+                "|Uint32List')",
+      "@Returns('Null|num|String|bool|JSExtendableArray|Float32List|Int32List"
+                "|Uint32List')",
     ],
 
     'WebGLRenderingContext.getVertexAttrib': [
@@ -283,14 +285,15 @@
     'WebGLRenderingContext.getParameter': [
       # Taken from http://www.khronos.org/registry/webgl/specs/latest/
       # Section 5.14.3 Setting and getting state
-      "@Creates('Null|num|String|bool|=List|Float32List|Int32List|Uint32List"
-                "|Framebuffer|Renderbuffer|Texture')",
-      "@Returns('Null|num|String|bool|=List|Float32List|Int32List|Uint32List"
-                "|Framebuffer|Renderbuffer|Texture')",
+      "@Creates('Null|num|String|bool|JSExtendableArray|Float32List|Int32List"
+                "|Uint32List|Framebuffer|Renderbuffer|Texture')",
+      "@Returns('Null|num|String|bool|JSExtendableArray|Float32List|Int32List"
+                "|Uint32List|Framebuffer|Renderbuffer|Texture')",
     ],
 
     'XMLHttpRequest.response': [
-      "@Creates('ByteBuffer|Blob|Document|=Object|=List|String|num')",
+      "@Creates('ByteBuffer|Blob|Document|=Object|JSExtendableArray|String"
+                "|num')",
     ],
 }, dart2jsOnly=True)
 
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 5f2a6d3..da2a88f 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -1028,6 +1028,8 @@
     'Future': TypeData(clazz='Interface', dart_type='Future'),
     'GamepadList': TypeData(clazz='Interface', item_type='Gamepad',
         suppress_interface=True),
+    'GLenum': TypeData(clazz='Primitive', dart_type='int',
+        native_type='unsigned'),
     'HTMLAllCollection': TypeData(clazz='Interface', item_type='Node'),
     'HTMLCollection': TypeData(clazz='Interface', item_type='Node'),
     'NamedNodeMap': TypeData(clazz='Interface', item_type='Node'),
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 53b2328..3d013e4 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -388,7 +388,6 @@
     'DOMWindow.webkitCancelRequestAnimationFrame',
     'DOMWindow.webkitIndexedDB',
     'DOMWindow.webkitRequestAnimationFrame',
-    'Document.adoptNode',
     'Document.alinkColor',
     'Document.all',
     'Document.applets',
@@ -424,7 +423,6 @@
     'Document.getOverrideStyle',
     'Document.getSelection',
     'Document.images',
-    'Document.importNode',
     'Document.linkColor',
     'Document.location',
     'Document.open',
diff --git a/tools/dom/src/WrappedList.dart b/tools/dom/src/WrappedList.dart
index b725b96..145c9ab 100644
--- a/tools/dom/src/WrappedList.dart
+++ b/tools/dom/src/WrappedList.dart
@@ -37,9 +37,9 @@
 
   void sort([int compare(E a, E b)]) { _list.sort(compare); }
 
-  int indexOf(E element, [int start = 0]) => _list.indexOf(element, start);
+  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);
 
-  int lastIndexOf(E element, [int start]) => _list.lastIndexOf(element, start);
+  int lastIndexOf(Object element, [int start]) => _list.lastIndexOf(element, start);
 
   void insert(int index, E element) => _list.insert(index, element);
 
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index b9885df..e213565 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -7,6 +7,10 @@
 // Auto-generated dart:html library.
 
 /// The Dart HTML library.
+///
+/// For examples, see
+/// [Dart HTML5 Samples](https://github.com/dart-lang/dart-html5-samples)
+/// on Github.
 library dart.dom.html;
 
 import 'dart:async';
@@ -25,7 +29,7 @@
 import 'dart:web_gl' as gl;
 import 'dart:web_sql';
 import 'dart:_js_helper' show convertDartClosureToJS, Creates, JavaScriptIndexingBehavior, JSName, Null, Returns;
-import 'dart:_interceptors' show Interceptor;
+import 'dart:_interceptors' show Interceptor, JSExtendableArray;
 import 'dart:_isolate_helper' show IsolateNatives;
 import 'dart:_foreign_helper' show JS;
 
@@ -42,7 +46,6 @@
 part '$AUXILIARY_DIR/KeyCode.dart';
 part '$AUXILIARY_DIR/KeyLocation.dart';
 part '$AUXILIARY_DIR/KeyName.dart';
-part '$AUXILIARY_DIR/PathObserver.dart';
 part '$AUXILIARY_DIR/Point.dart';
 part '$AUXILIARY_DIR/ReadyState.dart';
 part '$AUXILIARY_DIR/Rectangle.dart';
diff --git a/tools/dom/templates/html/dart2js/impl_KeyboardEvent.darttemplate b/tools/dom/templates/html/dart2js/impl_KeyboardEvent.darttemplate
index 7c4b25a..cea5133 100644
--- a/tools/dom/templates/html/dart2js/impl_KeyboardEvent.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_KeyboardEvent.darttemplate
@@ -3,6 +3,15 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+/**
+ * An event that describes user interaction with the keyboard.
+ *
+ * The [type] of the event identifies what kind of interaction occurred.
+ *
+ * See also:
+ *
+ * * [KeyboardEvent](https://developer.mozilla.org/en/DOM/KeyboardEvent) at MDN.
+ */
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 
   factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
index 8a96fbb..06d1e31 100644
--- a/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
@@ -14,6 +14,7 @@
 import 'dart:typed_data';
 import 'dart:_js_helper' show Creates, Returns, JSName, Null;
 import 'dart:_foreign_helper' show JS;
+import 'dart:_interceptors' show JSExtendableArray;
 
 $!GENERATED_DART_FILES
 
@@ -127,7 +128,7 @@
   return convertNativeToDart_AcceptStructuredClone(object, mustCopy: false);
 }
 
-
-const String _idbKey = '=List|=Object|num|String';  // TODO(sra): Add DateTime.
+// TODO(sra): Add DateTime.
+const String _idbKey = 'JSExtendableArray|=Object|num|String';
 const _annotation_Creates_IDBKey = const Creates(_idbKey);
 const _annotation_Returns_IDBKey = const Returns(_idbKey);
diff --git a/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
index ad41aba..a4124e7 100644
--- a/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
@@ -11,7 +11,7 @@
 import 'dart:typed_data';
 import 'dart:_js_helper' show Creates, JSName, Null, Returns, convertDartClosureToJS;
 import 'dart:_foreign_helper' show JS;
-import 'dart:_interceptors' show Interceptor;
+import 'dart:_interceptors' show Interceptor, JSExtendableArray;
 
 part '$AUXILIARY_DIR/WebGLConstants.dart';
 
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index 9c7b733..2cdb23b 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -6,6 +6,10 @@
 // Auto-generated dart:html library.
 
 /// The Dart HTML library.
+///
+/// For examples, see
+/// [Dart HTML5 Samples](https://github.com/dart-lang/dart-html5-samples)
+/// on Github.
 library dart.dom.html;
 
 import 'dart:async';
@@ -38,7 +42,6 @@
 part '$AUXILIARY_DIR/KeyCode.dart';
 part '$AUXILIARY_DIR/KeyLocation.dart';
 part '$AUXILIARY_DIR/KeyName.dart';
-part '$AUXILIARY_DIR/PathObserver.dart';
 part '$AUXILIARY_DIR/Point.dart';
 part '$AUXILIARY_DIR/ReadyState.dart';
 part '$AUXILIARY_DIR/Rectangle.dart';
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index a6e165d..c5bf740 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -13,7 +13,7 @@
     : _childElements = element.$dom_children,
       _element = element;
 
-  bool contains(Element element) => _childElements.contains(element);
+  bool contains(Object element) => _childElements.contains(element);
 
 
   bool get isEmpty {
diff --git a/tools/gyp/configurations_make.gypi b/tools/gyp/configurations_make.gypi
index eec4dc5..ba2445a 100644
--- a/tools/gyp/configurations_make.gypi
+++ b/tools/gyp/configurations_make.gypi
@@ -90,9 +90,7 @@
       },
 
       'Dart_Release': {
-        'cflags': [ '-O3',
-                    '-fno-omit-frame-pointer',
-        ],
+        'cflags': [ '-O3', ],
       },
     },
   },
diff --git a/tools/mac_build_editor_bundle.sh b/tools/mac_build_editor_bundle.sh
new file mode 100755
index 0000000..14b8054
--- /dev/null
+++ b/tools/mac_build_editor_bundle.sh
@@ -0,0 +1,121 @@
+#!/bin/bash
+# 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
+# BSD-style license that can be found in the LICENSE file.
+
+# Fail if a command failed
+set -e
+
+if [ $# -ne 5 ]; then
+  echo "Usage $0 <app-folder> <editor-build-directory> <dart-sdk> " \
+       "<Chromium.app> <icon.icns>"
+  exit 1
+fi
+
+OUTPUT_APP_FOLDER=$1
+INPUT_EDITOR_BUILD_DIRECTORY=$2
+INPUT_DART_SDK_DIRECTORY=$3
+INPUT_CHROMIUM_APP_DIRECTORY=$4
+INPUT_ICON_PATH=$5
+
+# Input validations
+if [ "${OUTPUT_APP_FOLDER##*.}" != "app" ]; then
+  echo "Application folder has to end in '.app' " \
+       "(but was $APP_FOLDER_NAME)."
+  exit 1
+fi
+if [ "${INPUT_ICON_PATH##*.}" != "icns" ]; then
+  echo "Application icon has to end in '.icns'."
+  exit 1
+fi
+
+function ensure_exists {
+  if [ ! -e "$1" ]; then
+    echo "Directory or file does not exist: $1."
+    exit 1
+  fi
+}
+ensure_exists "$INPUT_EDITOR_BUILD_DIRECTORY"
+ensure_exists "$INPUT_DART_SDK_DIRECTORY"
+
+# Remove old directory if present
+if [ -e "$OUTPUT_APP_FOLDER" ]; then
+  rm -r "$OUTPUT_APP_FOLDER"
+fi
+
+# Make directory structure and copy necessary files
+mkdir -p "$OUTPUT_APP_FOLDER/Contents/MacOS"
+LAUNCHER_SUBPATH="DartEditor.app/Contents/MacOS/DartEditor"
+cp "$INPUT_EDITOR_BUILD_DIRECTORY/$LAUNCHER_SUBPATH" \
+   "$OUTPUT_APP_FOLDER/Contents/MacOS/"
+cp "$INPUT_EDITOR_BUILD_DIRECTORY/$LAUNCHER_SUBPATH.ini" \
+   "$OUTPUT_APP_FOLDER/Contents/MacOS/"
+mkdir -p "$OUTPUT_APP_FOLDER/Contents/Resources"
+cp "$INPUT_ICON_PATH" "$OUTPUT_APP_FOLDER/Contents/Resources/dart.icns"
+cp -R "$INPUT_DART_SDK_DIRECTORY" \
+      "$OUTPUT_APP_FOLDER/Contents/Resources/dart-sdk"
+cp -R "$INPUT_CHROMIUM_APP_DIRECTORY" \
+   "$OUTPUT_APP_FOLDER/Contents/Resources/Chromium.app"
+for dirname in $(echo configuration plugins features samples); do
+  cp -R "$INPUT_EDITOR_BUILD_DIRECTORY/$dirname" \
+        "$OUTPUT_APP_FOLDER/Contents/Resources/"
+done
+
+EQUINOX_LAUNCHER_JARFILE=$(cd "$OUTPUT_APP_FOLDER"; \
+  ls Contents/Resources/plugins/org.eclipse.equinox.launcher_*.jar);
+
+EQUINOX_LAUNCHER_LIBRARY=$(cd "$OUTPUT_APP_FOLDER"; ls \
+  Contents/Resources/plugins/org.eclipse.equinox.launcher.cocoa.*/eclipse_*.so);
+
+cat > "$OUTPUT_APP_FOLDER/Contents/Info.plist" << EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
+          "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+    <key>NSHighResolutionCapable</key>
+      <true/>
+    <key>CFBundleExecutable</key>
+      <string>DartEditor</string>
+    <key>CFBundleGetInfoString</key>
+      <string>Eclipse 3.7 for Mac OS X, Copyright IBM Corp. and others 2002,
+              2011. All rights reserved.</string>
+    <key>CFBundleIconFile</key>
+      <string>dart.icns</string>
+    <key>CFBundleIdentifier</key>
+      <string>org.eclipse.eclipse</string>
+    <key>CFBundleInfoDictionaryVersion</key>
+      <string>6.0</string>
+    <key>CFBundleName</key>
+      <string>DartEditor</string>
+    <key>CFBundlePackageType</key>
+      <string>APPL</string>
+    <key>CFBundleShortVersionString</key>
+      <string>3.7</string>
+    <key>CFBundleSignature</key>
+      <string>????</string>
+    <key>CFBundleVersion</key>
+      <string>3.7</string>
+    <key>CFBundleDevelopmentRegion</key>
+      <string>English</string>
+    <key>CFBundleLocalizations</key>
+      <array>
+        <string>en</string>
+        <key>WorkingDirectory</key>
+        <string>\$APP_PACKAGE/Contents/Resources</string>
+      </array>
+    <key>Eclipse</key>
+      <array>
+        <string>-startup</string>
+        <string>\$APP_PACKAGE/$EQUINOX_LAUNCHER_JARFILE</string>
+        <string>--launcher.library</string>
+        <string>\$APP_PACKAGE/$EQUINOX_LAUNCHER_LIBRARY</string>
+        <string>-keyring</string><string>~/.eclipse_keyring</string>
+        <string>-showlocation</string>
+        <key>WorkingDirectory</key>
+        <string>\$APP_PACKAGE/Contents/Resources</string>
+      </array>
+  </dict>
+</plist>
+EOF
+
diff --git a/tools/mac_build_editor_dmg.sh b/tools/mac_build_editor_dmg.sh
new file mode 100755
index 0000000..2da8c0f
--- /dev/null
+++ b/tools/mac_build_editor_dmg.sh
@@ -0,0 +1,102 @@
+#!/bin/bash
+# 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
+# BSD-style license that can be found in the LICENSE file.
+
+# This is partly based on
+# https://bitbucket.org/rmacnak/nsvm/src/
+#   b2de52432a2baff9c4ada099430fb16a771d34ef/vm/onebuild/installer-Darwin.gmk
+
+# Fail if a command failed
+set -e
+
+if [ $# -ne 4 ]; then
+  echo "Usage $0 <output.dmg> <app-folder> <icon.icns> <volume-name>"
+  exit 1
+fi
+
+OUTPUT_DMG_FILE=$1
+INPUT_APP_FOLDER_PATH=$2
+INPUT_ICON=$3
+INPUT_VOLUME_NAME=$4
+
+APP_FOLDER_NAME=$(basename "$INPUT_APP_FOLDER_PATH")
+VOLUME_MOUNTPOINT="/Volumes/$INPUT_VOLUME_NAME"
+SPARSEIMAGE="$OUTPUT_DMG_FILE.sparseimage"
+
+# Input validations
+if [ "${INPUT_APP_FOLDER_PATH##*.}" != "app" ]; then
+  echo "Application folder has to end in '.app' " \
+       "(but was $INPUT_APP_FOLDER_PATH)."
+  exit 1
+fi
+if [ "${INPUT_ICON##*.}" != "icns" ]; then
+  echo "Volume icon has to end in '.icns'."
+  exit 1
+fi
+
+# If an old image is still mounted, umount it
+if [ -e "$VOLUME_MOUNTPOINT" ]; then
+  hdiutil eject "$VOLUME_MOUNTPOINT"
+fi
+
+# Remove old output files
+if [ -f "$SPARSEIMAGE" ]; then
+  rm "$SPARSEIMAGE"
+fi
+if [ -f "$OUTPUT_DMG_FILE" ]; then
+  rm "$OUTPUT_DMG_FILE"
+fi
+
+# Create a new image and attach it
+hdiutil create -size 300m -type SPARSE -volname "$INPUT_VOLUME_NAME" -fs \
+  'Journaled HFS+' "$SPARSEIMAGE"
+hdiutil attach "$SPARSEIMAGE"
+
+# Add link to /Applications (so the user can drag-and-drop into it)
+ln -s /Applications "$VOLUME_MOUNTPOINT/"
+# Copy our application
+ditto "$INPUT_APP_FOLDER_PATH" "$VOLUME_MOUNTPOINT/$APP_FOLDER_NAME"
+# Make sure that the folder gets opened when mounting the image
+bless --folder "$VOLUME_MOUNTPOINT" --openfolder "$VOLUME_MOUNTPOINT"
+# Copy the volume icon
+cp "$INPUT_ICON" "$VOLUME_MOUNTPOINT/.VolumeIcon.icns"
+
+# Set the 'custom-icon' attribute on the volume
+SetFile -a C "$VOLUME_MOUNTPOINT"
+
+# Use an applescript to setup the layout of the folder.
+osascript << EOF
+tell application "Finder"
+	tell disk "$INPUT_VOLUME_NAME"
+		open
+		tell container window
+			set current view to icon view
+			set toolbar visible to false
+			set statusbar visible to false
+			set position to {100, 100}
+			set bounds to {100, 100, 512, 256}
+		end tell
+		tell icon view options of container window
+			set arrangement to not arranged
+			set icon size to 128
+		end tell
+		set position of item "$APP_FOLDER_NAME" to {64, 64}
+		set position of item "Applications" to {320, 64}
+    eject
+	end tell
+end tell
+EOF
+
+# Wait until the script above has umounted the image
+while [ -e "$VOLUME_MOUNTPOINT" ]; do
+  echo "Waiting for Finder to eject $VOLUME_MOUNTPOINT"
+  sleep 2
+done
+
+# Compress the sparse image
+hdiutil convert "$SPARSEIMAGE" -format UDBZ -o "$OUTPUT_DMG_FILE"
+
+# Remove sparse image
+rm "$SPARSEIMAGE"
+
diff --git a/tools/test.dart b/tools/test.dart
index c2da69a..fc789bf 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -27,6 +27,7 @@
 import "dart:async";
 import "dart:io";
 import "dart:math" as math;
+import "testing/dart/browser_controller.dart";
 import "testing/dart/http_server.dart";
 import "testing/dart/record_and_replay.dart";
 import "testing/dart/test_options.dart";
@@ -92,6 +93,10 @@
   var recordingPath = firstConf['record_to_file'];
   var recordingOutputPath = firstConf['replay_from_file'];
 
+  // We set a special flag in the safari browser if we need to clear out
+  // the cache before running.
+  Safari.deleteCache = firstConf['clear_safari_cache'];
+
   if (recordingPath != null && recordingOutputPath != null) {
     print("Fatal: Can't have the '--record_to_file' and '--replay_from_file'"
           "at the same time. Exiting ...");
@@ -164,10 +169,9 @@
       maxBrowserProcesses = 1;
     } else if (conf['runtime'].startsWith('safari') &&
                conf['use_browser_controller']) {
-      // FIXME(kustermann/ricow): Remove this once the new browser_controller is
-      // stable.
-      maxBrowserProcesses = math.max(maxProcesses - 3, 1);
-      maxProcesses = math.max(maxProcesses -1, 1);
+      // Safari does not allow us to run from a fresh profile, so we can only
+      // use one browser.
+      maxBrowserProcesses = 1;
     }
 
     for (String key in selectors.keys) {
@@ -245,7 +249,6 @@
   }
   eventListener.add(new ExitCodeSetter());
 
-
   void startProcessQueue() {
     // Start process queue.
     new ProcessQueue(maxProcesses,
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index 52628f1..f3d0acc 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -15,12 +15,11 @@
   StringBuffer _stdout = new StringBuffer();
   StringBuffer _stderr = new StringBuffer();
   StringBuffer _usageLog = new StringBuffer();
-  // This function is called when the process is closed.
-  Completer _processClosedCompleter = new Completer();
-  // This is called after the process is closed, after _processClosedCompleter
-  // has been called, but before onExit. Subclasses can use this to cleanup
-  // any browser specific resources (temp directories, profiles, etc)
-  // The function is expected to do it's work synchronously.
+  // This is called after the process is closed, before the done future
+  // is completed.
+  // Subclasses can use this to cleanup any browser specific resources
+  // (temp directories, profiles, etc). The function is expected to do
+  // it's work synchronously.
   Function _cleanup;
 
   /** The version of the browser - normally set when starting a browser */
@@ -42,9 +41,9 @@
   /** Print everything (stdout, stderr, usageLog) whenever we add to it */
   bool debugPrint = false;
 
-  // This future will be lazily set when calling close() and will complete once
-  // the process did exit.
-  Future browserTerminationFuture;
+  // This future returns when the process exits. It is also the return value
+  // of close()
+  Future done;
 
   Browser();
 
@@ -90,30 +89,17 @@
 
   Future close() {
     _logEvent("Close called on browser");
-    if (browserTerminationFuture == null) {
-      var completer = new Completer();
-      browserTerminationFuture = completer.future;
-
-      if (process != null) {
-        _processClosedCompleter.future.then((_) {
-          process = null;
-          completer.complete(true);
-          if (_cleanup != null) {
-            _cleanup();
-          }
-        });
-
-        if (process.kill(ProcessSignal.SIGKILL)) {
-          _logEvent("Successfully sent kill signal to process.");
-        } else {
-          _logEvent("Sending kill signal failed.");
-        }
+    if (process != null) {
+      if (process.kill(ProcessSignal.SIGKILL)) {
+        _logEvent("Successfully sent kill signal to process.");
       } else {
-        _logEvent("The process is already dead.");
-        completer.complete(true);
+        _logEvent("Sending kill signal failed.");
       }
+      return done;
+    } else {
+      _logEvent("The process is already dead.");
+      return new Future.immediate(true);
     }
-    return browserTerminationFuture;
   }
 
   /**
@@ -123,6 +109,11 @@
   Future<bool> startBrowser(String command, List<String> arguments) {
     return Process.start(command, arguments).then((startedProcess) {
       process = startedProcess;
+      // Used to notify when exiting, and as a return value on calls to
+      // close().
+      var doneCompleter = new Completer();
+      done = doneCompleter.future;
+
       Completer stdoutDone = new Completer();
       Completer stderrDone = new Completer();
 
@@ -149,7 +140,11 @@
       process.exitCode.then((exitCode) {
         _logEvent("Browser closed with exitcode $exitCode");
         Future.wait([stdoutDone.future, stderrDone.future]).then((_) {
-          _processClosedCompleter.complete(exitCode);
+          process = null;
+          if (_cleanup != null) {
+            _cleanup();
+          }
+          doneCompleter.complete(exitCode);
         });
       });
       return true;
@@ -183,6 +178,16 @@
    */
   const String versionFile = "/Applications/Safari.app/Contents/version.plist";
 
+  /**
+   * Directories where safari stores state. We delete these if the deleteCache
+   * is set
+   */
+  static const List<String> CACHE_DIRECTORIES =
+      const ["Library/Caches/com.apple.Safari",
+             "Library/Safari",
+             "Library/Saved Application State/com.apple.Safari.savedState",
+             "Library/Caches/Metadata/Safari"];
+
 
   Future<bool> allowPopUps() {
     var command = "defaults";
@@ -191,14 +196,42 @@
                 "WebKit2JavaScriptCanOpenWindowsAutomatically",
                 "1"];
     return Process.run(command, args).then((result) {
-        if (result.exitCode != 0) {
-          _logEvent("Could not disable pop-up blocking for safari");
-          return false;
-        }
-        return true;
+      if (result.exitCode != 0) {
+        _logEvent("Could not disable pop-up blocking for safari");
+        return false;
+      }
+      return true;
     });
   }
 
+  Future<bool> deleteIfExists(Iterator<String> paths) {
+    if (!paths.moveNext()) return new Future.immediate(true);
+    Directory directory = new Directory(paths.current);
+    return directory.exists().then((exists) {
+      if (exists) {
+        _logEvent("Deleting ${paths.current}");
+        return directory.delete(recursive: true)
+	    .then((_) => deleteIfExists(paths))
+	    .catchError((error) {
+	      _logEvent("Failure trying to delete ${paths.current}: $error");
+	      return false;
+	    });
+      } else {
+        _logEvent("${paths.current} is not present");
+        return deleteIfExists(paths);
+      }
+    });
+  }
+
+  // Clears the cache if the static deleteCache flag is set.
+  // Returns false if the command to actually clear the cache did not complete.
+  Future<bool> clearCache() {
+    if (!deleteCache) return new Future.immediate(true);
+    var home = Platform.environment['HOME'];
+    Iterator iterator = CACHE_DIRECTORIES.map((s) => "$home/$s").iterator;
+    return deleteIfExists(iterator);
+  }
+
   Future<String> getVersion() {
     /**
      * Example of the file:
@@ -242,28 +275,38 @@
 
   Future<bool> start(String url) {
     _logEvent("Starting Safari browser on: $url");
-    // Get the version and log that.
     return allowPopUps().then((success) {
       if (!success) {
-        return new Future.immediate(false);
-      }
-      return getVersion().then((version) {
-        _logEvent("Got version: $version");
-        var args = ["'$url'"];
-        return new Directory('').createTemp().then((userDir) {
-          _cleanup = () { userDir.deleteSync(recursive: true); };
-          _createLaunchHTML(userDir.path, url);
-          var args = ["${userDir.path}/launch.html"];
-          return startBrowser(binary, args);
-        });
-      }).catchError((e) {
-        _logEvent("Running $binary --version failed with $e");
         return false;
+      }
+      return clearCache().then((cleared) {
+        if (!cleared) {
+          _logEvent("Could not clear cache");
+          return false;
+        }
+        // Get the version and log that.
+        return getVersion().then((version) {
+          _logEvent("Got version: $version");
+          return new Directory('').createTemp().then((userDir) {
+            _cleanup = () { userDir.deleteSync(recursive: true); };
+            _createLaunchHTML(userDir.path, url);
+            var args = ["${userDir.path}/launch.html"];
+            return startBrowser(binary, args);
+          });
+        }).catchError((error) {
+          _logEvent("Running $binary --version failed with $error");
+          return false;
+        });
       });
     });
   }
 
   String toString() => "Safari";
+
+  // Delete the user specific browser cache and profile data.
+  // Safari only have one per user, and you can't specify one by command line.
+  static bool deleteCache = false;
+
 }
 
 
@@ -609,12 +652,7 @@
     status.timeout = true;
     timedOut.add(status.currentTest.url);
     var id = status.browser.id;
-    status.browser.close().then((closed) {
-      if (!closed) {
-        // Very bad, we could not kill the browser.
-        print("could not kill browser $id");
-        return;
-      }
+    status.browser.close().then((_) {
       // We don't want to start a new browser if we are terminating.
       if (underTermination) return;
       var browser;
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index a26a8b3..d241705 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -315,6 +315,14 @@
               'bool'
               ),
           new _TestOptionSpecification(
+              'clear_safari_cache',
+              'Clear the safari cache (i.e., delete it).',
+              ['--clear_safari_cache'],
+              [],
+              false,
+              'bool'
+              ),
+          new _TestOptionSpecification(
               'local_ip',
               'IP address the http servers should listen on.'
               'This address is also used for browsers to connect.',
@@ -454,9 +462,56 @@
 
     List<Map> expandedConfigs = _expandConfigurations(configuration);
     List<Map> result = expandedConfigs.where(_isValidConfig).toList();
+    for (var config in result) {
+     config['_reproducing_arguments_'] =
+         _constructReproducingCommandArguments(config);
+    }
     return result.isEmpty ? null : result;
   }
 
+  // For printing out reproducing command lines, we don't want to add these
+  // options.
+  Set<String>  _blacklistedOptions = new Set<String>.from([
+    'progress', 'failure-summary', 'step_name', 'report', 'tasks', 'verbose',
+    'time', 'dart', 'drt', 'dartium', 'build_directory', 'append_logs',
+    'write_debug_log', 'local_ip', 'shard', 'shards',
+  ]);
+
+  List<String> _constructReproducingCommandArguments(Map config) {
+    var arguments = new List<String>();
+    for (var configKey in config.keys) {
+      if (!_blacklistedOptions.contains(configKey)) {
+        for (var option in _options) {
+          var configValue = config[configKey];
+          // We only include entries of [conf] if we find an option for it.
+          if (configKey == option.name && configValue != option.defaultValue) {
+            var isBooleanOption = option.type == 'bool';
+            // Sort by length, so we get the shortest variant.
+            var possibleOptions = new List.from(option.keys);
+            possibleOptions.sort((a, b) => (a.length < b.length ? -1 : 1));
+            var key = possibleOptions[0];
+            if (key.startsWith('--')) {
+              // long version
+              arguments.add(key);
+              if (!isBooleanOption) {
+                arguments.add("$configValue");
+              }
+            } else {
+              // short version
+              assert(key.startsWith('-'));
+              if (!isBooleanOption) {
+                arguments.add("$key$configValue");
+              } else {
+                arguments.add(key);
+              }
+            }
+          }
+        }
+      }
+    }
+    return arguments;
+  }
+
   /**
    * Determine if a particular configuration has a valid combination of compiler
    * and runtime elements.
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index f105505..8c8d7830 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -128,9 +128,24 @@
   }
   for (var i = 0; i < test.commands.length; i++) {
     var command = test.commands[i];
+    var commandOutput = test.commandOutputs[command];
     output.add('');
     output.add('Command[$i]: $command');
+    if (commandOutput != null) {
+      output.add('Took ${commandOutput.time}');
+    } else {
+      output.add('Did not run');
+    }
   }
+
+  var arguments = ['python', 'tools/test.py'];
+  arguments.addAll(test.configuration['_reproducing_arguments_']);
+  arguments.add(test.displayName);
+  var testPyCommandline = arguments.map(escapeCommandLineArgument).join(' ');
+
+  output.add('');
+  output.add('Short reproduction command (experimental):');
+  output.add("    $testPyCommandline");
   return output;
 }
 
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 63c8164..73c9cba 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -116,8 +116,9 @@
       executable = executable.replaceAll('/', '\\');
     }
     var quotedArguments = [];
-    arguments.forEach((argument) => quotedArguments.add('"$argument"'));
-    commandLine = "\"$executable\" ${quotedArguments.join(' ')}";
+    quotedArguments.add(escapeCommandLineArgument(executable));
+    quotedArguments.addAll(arguments.map(escapeCommandLineArgument));
+    commandLine = quotedArguments.join(' ');
   }
 
   String toString() => commandLine;
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart
index 4c8170f..3ddf330 100644
--- a/tools/testing/dart/utils.dart
+++ b/tools/testing/dart/utils.dart
@@ -75,3 +75,12 @@
   return utf.decodeUtf8(bytes);
 }
 
+// This function is pretty stupid and only puts quotes around an argument if
+// it the argument contains a space.
+String escapeCommandLineArgument(String argument) {
+  if (argument.contains(' ')) {
+    return '"$argument"';
+  }
+  return argument;
+}
+
diff --git a/tools/utils.py b/tools/utils.py
index da42666..8346d09 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -239,9 +239,11 @@
   return output.strip()
 
 def GetSVNRevision():
+  custom_env = dict(os.environ)
+  custom_env['LC_MESSAGES'] = 'en_GB'
   p = subprocess.Popen(['svn', 'info'], stdout = subprocess.PIPE,
                        stderr = subprocess.STDOUT, shell=IsWindows(),
-                       env = {'LC_MESSAGES' : 'en_GB'})
+                       env = custom_env)
   output, not_used = p.communicate()
   revision = ParseSvnInfoOutput(output)
   if revision:
diff --git a/utils/apidoc/apidoc.dart b/utils/apidoc/apidoc.dart
index ef6bae5..3a4d605 100644
--- a/utils/apidoc/apidoc.dart
+++ b/utils/apidoc/apidoc.dart
@@ -148,7 +148,7 @@
       }
 
       if (new File.fromPath(libPath).existsSync()) {
-        apidocLibraries.add(_pathToFileUri(libPath.toNativePath()));
+        apidocLibraries.add(pathos.toUri(libPath.toNativePath()));
         includedLibraries.add(libName);
       } else {
         print('Warning: could not find package at $path');
@@ -162,7 +162,7 @@
     for (var lib in extraLibraries) {
       var libPath = new Path('../../$lib');
       if (new File.fromPath(libPath).existsSync()) {
-        apidocLibraries.add(_pathToFileUri(libPath.toNativePath()));
+        apidocLibraries.add(pathos.toUri(libPath.toNativePath()));
         var libName = libPath.filename.replaceAll('.dart', '');
         includedLibraries.add(libName);
       }
@@ -211,11 +211,9 @@
    */
   String mdnUrl = null;
 
-  Apidoc(this.mdn, Path outputDir, int mode,
-         bool generateAppCache, [excludedLibraries, String version]) {
-    if (?excludedLibraries) {
-      this.excludedLibraries = excludedLibraries;
-    }
+  Apidoc(this.mdn, Path outputDir, int mode, bool generateAppCache,
+      [List<String> excludedLibraries, String version]) {
+    if (excludedLibraries != null) this.excludedLibraries = excludedLibraries;
     this.version = version;
     this.outputDir = outputDir;
     this.mode = mode;
@@ -481,13 +479,3 @@
   }
 }
 
-/** Converts a local path string to a `file:` [Uri]. */
-Uri _pathToFileUri(String path) {
-  path = pathos.absolute(path);
-  if (Platform.operatingSystem != 'windows') {
-    return Uri.parse('file://$path');
-  } else {
-    return Uri.parse('file:///${path.replaceAll("\\", "/")}');
-  }
-}
-
diff --git a/utils/apidoc/apidoc.gyp b/utils/apidoc/apidoc.gyp
index d393354..67e31b2 100644
--- a/utils/apidoc/apidoc.gyp
+++ b/utils/apidoc/apidoc.gyp
@@ -87,8 +87,10 @@
             '--exclude-lib=analyzer_experimental',
             '--exclude-lib=browser',
             '--exclude-lib=dartdoc',
+            '--exclude-lib=docgen',
             '--exclude-lib=expect',
             '--exclude-lib=http',
+            '--exclude-lib=http_server',
             '--exclude-lib=oauth2',
             '--exclude-lib=pathos',
             '--exclude-lib=scheduled_test',